写作与公文
需要把 HTML、Markdown、文本…
把 HTML、markdown、文本、任意文件或构建后的多文件站点发布到 brewpage.app,获取即时公开 URL,并处理命名空间、密码、TTL、历史 token 与站点入口。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
需要把 HTML、Markdown、文本特定
解决思路
- 解析参数:`--ttl N`(TTL 天数,默认 `15`)、`--entry <filename>`(SITE 入口文件,默认自动检测),剩余文本作为 `content_arg`。
- 检测内容类型:`content_arg` 是目录(`test -d`)→ SITE,用 `POST /api/sites`(目录自动 zip,主路径);`content_arg` 以 `.zip` 结尾且文件存在(`test -f`)→ SITE,用 `POST /api/sites`(上传预构建归档);`content_arg` 是文件路径且文件存在(`test -f`)→ FILE,用 `POST /api/files`(multipart);其他 → HTML,用 `POST /api/html` 且 `format=markdown`。
- 模式规则:目录/ZIP → SITE;单文件 → FILE;其他 → HTML(markdown)。`POST /api/sites` 只接受 multipart `archive=@file.zip`,没有原始文件夹上传,所以目录需即时 zip(归档封装保留相对路径)。
- 统计各类型:SITE(目录)统计 HTML 数量、总大小、入口文件;SITE(ZIP)统计文件大小、入口覆盖;FILE 统计大小和 MIME(`file --mime-type -b`);TEXT 统计字符数。
- HTML/FILE 发布前显示统计:`Content: <type description> · <size> · <api endpoint>`;`TTL: <N> days`。
- SITE 入口检测优先级:`--entry` 标志 > 存在 `index.html` > 按字母序第一个 `.html` 文件。
- 压缩前运行 built-static guard:只发布构建产物,绝不发布项目源码。
- 如果目录没有 `.html` → 明确失败:`No .html found — build the site first, then point at the build output directory.`,不要猜入口。
- 如果目录像未构建源码(有 `package.json` + `src/` 但没有顶层 `.html`)→ 警告并请用户改指向构建输出(`dist/`、`build/`、`out/`、`_site/` 或 `public/`),不要 zip 源码树。
- SITE 发布前显示统计:`Content: site · <N> files · <total_size> · POST /api/sites`;`Entry: <entry_file>`;`TTL: <N> days`。
- 询问 namespace:说明它决定 URL 前缀和 brewpage.app 画廊可见性。选项:1) `public`(默认,画廊可见);2) 自动建议的 6-8 字符 slug;3) 自定义 namespace;4) 跳过 → `public`。回复数字或自定义 namespace(字母数字,3-32 字符)。
- 自动建议 namespace:根据内容上下文生成有意义短 slug(3-16 字符,小写字母数字 + 连字符)。文件 → 主题/用途(如 `api-docs`、`login-page`、`report-q2`);文本/HTML → 主要主题或标题(如 `pricing`、`team-intro`、`changelog`);站点 → 站点标题或目录名(如 `portfolio`、`docs-site`);不明确时用项目名或目录名。绝不用随机字符串或截断文件名。
- namespace 解析:`1`、`4` 或空 → `public`;`2` → 建议 slug;`3` 或任何其他字符串 → 按原样使用。
- 询问密码:说明密码保护(如果设置,页面从画廊隐藏)。选项:1) 无密码(默认);2) 随机 6 字符密码(如 `kx7p2m`);3) 自定义密码(至少 4 字符);4) 跳过 → 无密码。回复数字或自定义密码。
- 生成随机密码:运行 shell `LC_ALL=C tr -dc 'a-z0-9' < /dev/urandom | head -c6 2>/dev/null`。
- 密码解析:`1`、`4` 或空 → 无密码;`2` → 使用生成的随机密码;`3` 或自定义文本 → 按原样使用。
- 安全:ownerToken 绝不能出现在对话输出中。发布 bash 块原子处理 curl + token 解析 + history 保存;模型只看到 URL。每块先设置 `PASS_H`(无密码时为空数组)并使用 `"${PASS_H[@]}"` 引号形式;密码绝不字符串插值进命令。site-dir zip 排除项(`.git/`、`.env*` 等)也是防泄密措施。
- History 文件为工作区相对路径:`./brewpage-history.md`。
- 发布前初始化 history 文件(只运行一次):若 `./brewpage-history.md` 不存在,则写入头部。头部说明:PRIVATE FILE — keep this out of version control and never share it;owner tokens 允许删除和原地重新发布(html/json/kv/sites 都支持 PUT);删除 html/json/kv:`curl -s -X DELETE 'https://brewpage.app/api/{ns}/{id}' -H 'X-Owner-Token: TOKEN'`;删除 site:`curl -s -X DELETE 'https://brewpage.app/api/sites/{ns}/{id}' -H 'X-Owner-Token: TOKEN'`;更新 site(保持同一 URL):`PUT /api/sites/{ns}/{id}` 带 `X-Owner-Token: TOKEN` 和新 bundle,上传的 bundle 完全替换文件集(添加新文件、移除缺失文件、覆盖匹配),链接不变。表格列为 `| Date | URL | Owner Token | TTL | Type |`。
- 根据检测类型运行以下发布块之一;每块假设 history 文件已由初始化步骤创建。
- HTML/Markdown 文本发布:用 shell 将 `{content}` 读入 `CONTENT`,用 `jq -n --arg c "$CONTENT" '{content: $c}'` 构造 `PAYLOAD`;`PASS_H=()`,有密码时 `PASS_H=(-H "X-Password: $PASSWORD")`;`curl -s -X POST 'https://brewpage.app/api/html?ns={ns}&ttl={days}&format=markdown' -H 'Content-Type: application/json' "${PASS_H[@]}" -d "$PAYLOAD"`;从响应取 `.link` 和 `.ownerToken`;成功时把 `| date | [URL](URL) | TOKEN | {ttl}d | html |` 追加到 `$HISTORY_FILE`,打印 `OK $URL`;失败打印 `FAILED: $RESPONSE`。
- 文件发布:`PASS_H=()`,有密码时加 `-H "X-Password: $PASSWORD"`;`curl -s -X POST 'https://brewpage.app/api/files?ns={ns}&ttl={days}' "${PASS_H[@]}" -F 'file=@/absolute/path/to/file'`;解析 `.link` 和 `.ownerToken`;成功时把 `file` 类型行追加到 `$HISTORY_FILE`,打印 `OK $URL`;失败打印 `FAILED: $RESPONSE`。
- 站点(目录)发布:`PASS_H=()`,有密码时加 `-H "X-Password: $PASSWORD"`;`TMPZIP=$(mktemp /tmp/brewpage-site-XXXXXX.zip)`;在目录内执行 `zip -r "$TMPZIP" . -x '.git/*' '*/.git/*' '.env' '.env.*' '*/.env' '*/.env.*' 'node_modules/*' '*/node_modules/*' '.DS_Store' '*/.DS_Store' 'Thumbs.db' '.idea/*' '*/.idea/*' '.vscode/*' '*/.vscode/*' '.cache/*' '*/.cache/*' '*.map' '*.log'`;`curl -s -X POST 'https://brewpage.app/api/sites?ns={ns}&ttl={days}&entry={entry}' -H 'User-Agent: OpenClaw/1.0' "${PASS_H[@]}" -F "archive=@$TMPZIP"`;删除临时 zip;解析 `.link`、去掉尾部 `/`、取 `.ownerToken` 和 `.fileCount`;成功时追加 `site ($FCOUNT files)` 行,打印 `OK $URL | Files: $FCOUNT`;失败打印 `FAILED: $RESPONSE`。
- 站点(ZIP 文件)发布:`PASS_H=()`,有密码时加 `-H "X-Password: $PASSWORD"`;`curl -s -X POST 'https://brewpage.app/api/sites?ns={ns}&ttl={days}&entry={entry}' -H 'User-Agent: OpenClaw/1.0' "${PASS_H[@]}" -F 'archive=@{zip_file_path}'`;解析 `.link`、去掉尾部 `/`、取 `.ownerToken` 和 `.fileCount`;成功时追加 `site ($FCOUNT files)` 行,打印 `OK $URL | Files: $FCOUNT`;失败打印 `FAILED: $RESPONSE`。
- 输出成功结果(非 SITE):bash 打印 `OK {url}` 时,对话输出 `Published: {url from bash output}` 和 `Owner token saved to ./brewpage-history.md`。
- 输出 SITE 成功结果:bash 打印 `OK {url} | Files: {count}` 时,对话输出 `Published site: {url from bash output}`、`Entry: {entry_file} | Files: {count}`、`Owner token saved to ./brewpage-history.md`。警告:按打印原样分享 URL,不要追加尾部斜杠。brewpage.app 把 `/public/<id>/` 路由到自己的 landing page,挽救 no-slash 形式的 redirect 对 slash-dir 形式不触发。
- 绝不在对话中打印 ownerToken;token 只存在于 history 文件。
- 错误处理:bash 打印 `FAILED: ...` 时,对话输出 `Publish failed.`。
- Notes:始终对 curl `-F 'file=@...'` 使用绝对文件路径。
- Notes:使用 `jq -n --arg c "$CONTENT" '{content: $c}'` 安全编码文本内容。`format` 是查询参数,不是 body 字段——`/api/html` 忽略 JSON body 里的 `format` key,只读取 URL 的 `?format=`;放错位置会让服务器应用默认 `html`,把 markdown 当原始文本存储。
- Notes:TTL 默认 `15` 天。Namespace 必须字母数字(3-32 字符),默认 `public`。
- Notes:删除已发布页面时,在 `./brewpage-history.md` 找 owner token,并使用该文件头部展示的 delete 命令。
- Notes:更新已发布站点时,用 `X-Owner-Token` 把新 bundle `PUT` 到同一站点 URL(`PUT /api/sites/{ns}/{id}`);上传的 bundle 完全替换文件集(添加新文件、移除缺失文件、覆盖匹配),链接永不改变,无需 DELETE-then-POST。
- Notes:Sites 的主要输入是目录——它会被自动 zip(`POST /api/sites` 唯一接受的形式),从而封装相对路径。预构建 `.zip` 是备选输入,按原样上传。始终发布构建输出(`dist/`、`build/`、`out/`、`_site/`、`public/`),绝不发布项目源码。
- Notes:auto-zip 排除 `.git/`、`.env`/`.env.*`、`node_modules/`、编辑器/OS 垃圾、sourcemaps 和 logs——这是有意的防泄密措施,防止凭证和 VCS 历史进入公开归档。
- Notes:入口文件检测:`--entry` 覆盖 > `index.html` > 按字母序第一个 `.html`。
- Notes:SITE URL 无尾部斜杠。API 返回 `.link = 'https://brewpage.app/public/<id>'` 不带尾部 `/`;追加 `/` 会路由到 brewpage.app 自己的 landing page,挽救 no-slash 形式的 JS redirect 不对 slash-dir 形式触发,站点不可访问。
- Notes:SITE 验证不能通过 `curl` 完成。no-slash URL 提供 BrewPage landing HTML 和内联 JS redirect,只在真实浏览器执行;用真实浏览器验证,或显式抓取 `<url>/index.html`。
适用边界 · 注意事项
- 需要自托管、私有网络、长期稳定持久化、SLA、自定义域名或服务端逻辑时,不适用 brewpage.app 免费托管。
- 不要发布项目源码或未构建代码;必须先构建,并且不要把密钥/敏感数据放进要发布的归档。
- 需要强权限控制或内部认证访问时不适合;密码保护主要用于从画廊隐藏页面,不等于完整安全边界。