Doramagic 项目包 · 项目说明书
pagecast 项目
预览本地 HTML 报告、Markdown 文档和静态小应用,并一键发布。
Pagecast 概览与系统架构
Pagecast 是一个本地优先的发布工具,主要面向 AI 编码代理(Claude Code、Codex、Cursor 等)生成的 HTML 报告、Markdown 文档以及小型静态 Web 项目。它的核心价值是把本地保存的 .html/.htm/.md/.markdown 文件一键转化为运行在用户自有 Cloudflare Pages 账户上的可分享公共链接。资料来源:[...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
项目定位与适用场景
Pagecast 是一个本地优先的发布工具,主要面向 AI 编码代理(Claude Code、Codex、Cursor 等)生成的 HTML 报告、Markdown 文档以及小型静态 Web 项目。它的核心价值是把本地保存的 .html/.htm/.md/.markdown 文件一键转化为运行在用户自有 Cloudflare Pages 账户上的可分享公共链接。资料来源:README.md:1-12
适合的场景:Playwright/Lighthouse 报告、数据仪表盘、计划书、设计文档、发布说明,以及构建后的 dist/build/out 静态站点。不适合的场景:私有草稿、需要后端运行时才能工作的服务(必须先导出为静态资产)。资料来源:README.md:13-19
系统架构总览
整个系统由三层组成:本地应用层、Cloudflare 部署层、以及配套的浏览器扩展与代理技能。
graph TB
subgraph 本地环境["本地环境(Node.js >= 20)"]
CLI["pagecast CLI (src/cli.js)"]
Server["pagecast Server (src/server.js)"]
MD["Markdown 渲染器 (src/markdown.js)"]
Store[(".pagecast/ 数据目录")]
end
subgraph 浏览器侧["浏览器侧"]
Ext["Chrome 扩展 (extension/manifest.json)"]
Popup["Popup/右键菜单"]
end
subgraph Cloudflare["用户自有 Cloudflare 账户"]
Pages["Cloudflare Pages<br/>/p/<token>/ 公共 URL"]
Worker["Feedback Worker (feedback/worker.js)"]
KV["PAGECAST_FEEDBACK KV"]
end
subgraph 代理生态["AI 代理生态"]
Skill["publish-report 技能"]
Hook["PostToolUse 钩子"]
end
CLI --> Server
Server --> MD
Server --> Store
Server -->|"部署资产"| Pages
Server -->|"配置 wrangler.toml"| Worker
Worker --> KV
Ext -->|"POST /api/publish-local"| Server
Popup --> Ext
Skill --> CLI
Hook --> Skill关键设计原则:用户本地运行的服务器直接与用户自己的 Cloudflare 账户通信——中间没有 Pagecast 托管的中转层,因此无需在 Pagecast 注册账户,也不用担心服务被取消("no Pagecast-hosted middleman")。资料来源:extension/store/listing.md:21-27
核心组件与职责
| 组件 | 路径 | 职责 |
|---|---|---|
| CLI 入口 | src/cli.js | 解析命令行参数,提供 npx pagecast 启动本地服务 |
| HTTP 服务 | src/server.js | 暴露管理 UI(127.0.0.1:4173)、本地预览(4174)、/api/publish-local 等接口,调用 Wrangler 部署 |
| Markdown 渲染器 | src/markdown.js | 零依赖的 Markdown 渲染子集,严格转义 HTML/属性,URL 走安全白名单 |
| Chrome 扩展 | extension/manifest.json、extension/background.js、extension/popup.js | 在 file:// 页面提供一键发布(工具栏按钮或右键菜单) |
| 反馈 Worker | feedback/worker.js | 收集已发布页面的浏览量、表情反应、国家/设备/来源粗粒度统计 |
| 代理技能 | plugin/skills/publish-report/SKILL.md | 指导 AI 代理在生成可分享产物时主动询问"是否用 Pagecast 发布" |
package.json 的 bin 字段把 pagecast 命令映射到 src/cli.js,exports 指向 src/server.js,本地与库式调用共用同一份入口;files 数组声明发布到 npm 时包含 src/、public/、plugin/、feedback/ 以及技能文件。资料来源:package.json:5-32
发布流程与运行模式
1. 本地启动
执行 npx pagecast 后,CLI 启动本地服务并打开管理 UI;本地数据与配置存放在当前目录下的 .pagecast/ 中。资料来源:README.md:23-33
2. Cloudflare 一次性连接
首次使用在管理 UI 中点击 Connect Cloudflare。OAuth 完成后 Pagecast 会自动创建 Pages 项目;子域名不一定等于项目名——pagesBaseUrlFromDeployOutput 会从 Wrangler 输出中解析 <deploy-hash>.<subdomain>.pages.dev 形式。资料来源:src/server.js:pagesBaseUrlFromDeployOutput
3. 发布一条新链接(默认模式)
npx pagecast publish "/abs/path/report.md" --json
# → {"ok":true,"url":"https://pagecast.pages.dev/p/<token>/", ...}
- Markdown 文件由
src/markdown.js渲染为自包含、安全加固的 HTML 文档(公开页面的文本/代码先转义,URL 走sanitizeUrl白名单)。资料来源:src/markdown.js:1-35 - 通过 Wrangler 将文件部署到用户的 Pages 项目,生成形如
/p/<token>/的公共路径。资料来源:llms.txt:21-32
4. 整站部署(直接模式)
npx pagecast pages deploy "/abs/path/dist" --project pagecasthq --branch main --json
该模式会覆盖目标 Pages 项目的内容,适用于把整个 dist 推上去;不传 --branch 时默认 main。资料来源:llms.txt:28-32
5. 浏览器扩展入口
Chrome 扩展通过 host_permissions: ["http://127.0.0.1/*", "http://localhost/*"] 调用本地服务的 /api/publish-local;右键菜单项 pagecast-publish 仅在 file:// 页面且 URL 命中 /\.(html?|md|markdown)(?:[?#].*)?$/i 时启用。资料来源:extension/manifest.json:1-25、extension/background.js:1-19
6. 反馈与统计
发布页面内嵌 widget.js(由反馈 Worker 提供),浏览/表情反应以聚合形式写入 KV(stats:<slug>),只存国家/来源主机/设备类等粗粒度信号,不存 IP/Cookie/个人数据。资料来源:feedback/worker.js:1-15
过期链接与社区设计取舍
v0.1.6 引入过期 URL 能力:过期时间在边缘(与密码保护共用的 Pages Function)强制检查,到期即失效;用户关机期间链接仍按计划死亡。这是默认 30 天、可按安装/按发布覆盖的策略。资料来源:plugin/skills/publish-report/SKILL.md:相关段落
社区里有用户提问"为什么是 Pages 而非 Workers with Static Assets"——这正是当前架构的明确取舍:项目依赖 Pages 自带的静态托管 + Functions(用于过期/密码校验),URL 解析逻辑也是按 Wrangler 的 Pages 部署输出格式实现的;Workers with Static Assets 当时并不具备等价的静态资源原语,作者未来可能据此再评估。资料来源:src/server.js:URL 解析段
常见错误模式
401:OAuth 未完成或已过期,需运行npx pagecast pages setup或在 UI 中重新连接 Cloudflare。资料来源:llms.txt:39-43409:检测到多个 Cloudflare 账户,需传--account <account-id>或在 UI 中选择。资料来源:llms.txt:39-43- OAuth 缺少 Workers/KV 权限:部署反馈 Worker 时会触发 Cloudflare
code: 10000/authentication error,server.js会自动用扩展后的FEEDBACK_OAUTH_SCOPES重新登录并重试。资料来源:src/server.js:FEEDBACK_OAUTH_SCOPES 重试段 - 扩展提示"Pagecast isn't running":本地服务未启动,按提示执行
npx pagecast即可。资料来源:extension/popup.js:状态检查段
另请参阅
- 发布工作流与代理技能:plugin/skills/publish-report/SKILL.md
- 浏览器扩展商店上架材料:extension/store/SUBMIT.md
- 反馈 Worker 实现:feedback/worker.js
- 面向 LLM/代理的入口说明:llms.txt
来源:https://github.com/Amal-David/pagecast / 项目说明书
核心功能与发布流程
Pagecast 是一个本地优先的发布工具,专注于把本地生成的 HTML 报告、Markdown 文档以及小型静态站点(dist/build/out)一键发布到用户自己的 Cloudflare Pages 账户,从而获得可分享的公开链接 资料来源:[README.md:1-15]()。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
Pagecast 是一个本地优先的发布工具,专注于把本地生成的 HTML 报告、Markdown 文档以及小型静态站点(dist/build/out)一键发布到用户自己的 Cloudflare Pages 账户,从而获得可分享的公开链接 资料来源:README.md:1-15。
整个项目以零全局安装的 npx pagecast 命令启动,兼具本地管理界面、命令行接口和代理插件三种使用形态,适合人类开发者和 AI 编码代理(Claude Code、Codex、Cursor 等)共同使用 资料来源:README.md:31-40。
核心功能模块
1. 本地预览与管理界面
启动后 Pagecast 暴露两个本地端口:
| 端点 | 用途 |
|---|---|
http://127.0.0.1:4173 | 管理后台(Admin UI) |
http://127.0.0.1:4174 | 已发布页面的本地预览(保留 /p/<slug>/ 真实路径形态) |
所有数据与配置(已发布页面、Cloudflare 凭据、反馈密钥等)统一保存在当前工作目录的 .pagecast/ 文件夹中,便于迁移和版本控制 资料来源:README.md:33-40。
管理界面基于 React + TypeScript 实现,支持对已发布页面进行拖拽排序、选择、删除、撤销、重新同步等操作 资料来源:web/src/App.tsx:46-78。
2. 零依赖 Markdown 渲染器
考虑到发布的页面是公开的,Pagecast 自带一个零依赖的安全加固 Markdown 渲染器 src/markdown.js,主要安全策略包括:
- 文本/代码片段在输出前必须经过
escapeHtml转义三个结构字符& < > - 属性值额外通过
escapeAttribute转义双引号,防止恶意 URL/alt 文本逃逸属性 - 链接与图片 URL 走
sanitizeUrl严格白名单:javascript:、data:、vbscript:、file:等危险 scheme 一律降级为#
资料来源:src/markdown.js:8-37
3. 发布到 Cloudflare Pages
发布核心逻辑封装在 createCloudflarePagesPublisher 中。它使用用户本地的 Wrangler 凭据,将 pages-deploy 目录推送到用户的 Pages 项目。每个发布页在发布前会自动注入以下元素:
- 反馈/分析 Widget(当反馈 Worker 已配置时),用于收集浏览量与表情反应
- "Published with Pagecast" 徽章(可在白名单场景下关闭)
- Open Graph / Twitter 社交元数据,使分享链接展开时呈现富卡片
4. 反馈与统计分析
Pagecast 在用户账户下部署一个轻量 Cloudflare Worker(feedback/worker.js),用于承载:
- 浏览量(views)
- 表情反应(
👍❤️🎉🚀👀五个内置白名单) - 国家(来自
cf.country)、引荐来源(仅 host,不含完整 URL)、设备分类(粗粒度)
所有统计以单页聚合形式存储在 KV(stats:<slug>),KV 不支持原子递增,故统计为尽力而为(best-effort)。隐私上不存储 IP、Cookie、个人访客记录或 PII 资料来源:feedback/worker.js:1-20。
5. v0.1.6 过期链接(Expiring URLs)
最新版本中,每个发布链接可设置过期窗口(数小时 / 1 天 / 2 天 / 7 天 / 30 天 / Never),默认 30 天,支持安装级默认配置和发布级覆盖。过期检查在边缘由 Cloudflare Pages Function 强制执行,即使用户机器离线链接也会准时失效 资料来源:community_context #v0.1.6。
发布流程
下面是 Pagecast 的一次完整发布流程(从文件落地到获得公开 URL):
flowchart TD
A[用户在本地生成<br>HTML/Markdown 文件] --> B{触发方式}
B -->|CLI| C[npx pagecast publish<br>绝对路径 --json]
B -->|编码代理| D[$publish-report 技能<br>询问并执行]
B -->|Chrome 扩展| E[工具栏按钮 / 右键菜单]
C --> F[本地 Markdown 渲染<br>src/markdown.js]
D --> F
E --> F
F --> G[注入反馈 Widget + 徽章 + OG Meta]
G --> H[Wrangler 推送至<br>用户 Cloudflare Pages 项目]
H --> I[返回公开 URL<br>https://*.pages.dev/p/<slug>/]
I --> J[反馈 Worker 接收<br>浏览/反应信标]关键命令速查 资料来源:llms.txt:11-23:
# 一次性 Cloudflare 授权
npx pagecast pages setup --project pagecast --json
# 发布 HTML/Markdown 报告
npx pagecast publish "/abs/path/report.html" --json
npx pagecast publish "/abs/path/report.md" --json
# 部署整个静态目录到 Pages 项目
npx pagecast pages deploy "/abs/path/dist" --project pagecasthq --branch main --json
与社区关注的关联
社区中一个被反复问到的设计问题是:为什么选择 Cloudflare Pages 而非 Workers + Static Assets? 这是 Pagecast 当前架构的核心取舍——它依托 Pages Functions 在边缘执行过期检查和密码保护 资料来源:community_context #Pages-not-Workers,因此在 Pages Functions 继续作为边缘执行点的前提下,过期 URL(v0.1.6)等功能得以在用户的 Pages 项目中本地完成而无需引入 D1 或 Durable Objects。
常见失败模式
401 未授权:运行npx pagecast pages setup重新连接 Cloudflare 资料来源:llms.txt:39-41409 多账户冲突:通过--account <account-id>指定账户,或在管理界面中选择 资料来源:llms.txt:42-43- 首次部署无 workers.dev URL:需在 Cloudflare 控制台启用
workers.dev子域后再重试 资料来源:src/server.js:208-220 - 反馈权限不足:Wrangler 报
code: 10000时,Pagecast 会自动升级 OAuth scope 后重试一次 资料来源:src/server.js:222-236
See Also
- README.md — 项目总览与快速上手
- plugin/skills/publish-report/SKILL.md — AI 代理发布技能规范
- extension/store/listing.md — Chrome 扩展商店文案
- llms.txt — 给 AI 代理的命令参考
资料来源:src/markdown.js:8-37
AI 代理集成与浏览器扩展
Pagecast 围绕"本地优先 + 一键发布"的设计理念,将本地的 HTML / Markdown 报告、规划文档、静态迷你应用转成可分享的 Cloudflare Pages 公网链接。其面向 AI 代理与终端用户的入口由两条独立但互补的通道构成:AI 代理侧通过 plugin/ 目录下的 Skill + Hook 组合接入 Claude Code、Codex、Curso...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述与定位
Pagecast 围绕"本地优先 + 一键发布"的设计理念,将本地的 HTML / Markdown 报告、规划文档、静态迷你应用转成可分享的 Cloudflare Pages 公网链接。其面向 AI 代理与终端用户的入口由两条独立但互补的通道构成:AI 代理侧通过 plugin/ 目录下的 Skill + Hook 组合接入 Claude Code、Codex、Cursor 等 Agent Skills 兼容工具;终端用户侧通过 Chrome 浏览器扩展在浏览 file:// 页面时一键发布。资料来源:README.md 与 plugin/README.md。
项目关键词在 package.json 中被显式声明:codex、claude-code、ai-agents、agent-skill 等。资料来源:package.json。llms.txt 进一步明确:发布动作必须得到用户的明确确认,代理不可静默发布任何文件。资料来源:llms.txt。
AI 代理插件架构
核心组件:Skill 与 Hook
Pagecast 的代理集成采用"被动提示 + 主动技能"的双层设计。
- Skill (
plugin/skills/publish-report/SKILL.md):一份为代理阅读的 Markdown 提示词,描述"何时提议发布"、"如何调用 CLI"以及"如何维护一个目标进度页面"。其description字段明确指出——代理在生成 HTML / Markdown 报告、规划、仪表盘或构建出静态站点后,应主动提议使用 Pagecast 发布。资料来源:plugin/skills/publish-report/SKILL.md。 - Hook (
plugin/hooks/hooks.json+detect-report.mjs+detect-artifacts-on-stop.mjs):在 Claude Code 中通过PostToolUse钩子监测文件写入事件;当代理写出.html/.htm/.md/.markdown文件时,向代理发出一条提示,引导其调用publish-report技能。资料来源:plugin/hooks/hooks.json 与 plugin/hooks/detect-report.mjs。
工作流(一次性快照 vs 持续目标页)
Skill 中区分了两类典型工作流:
| 场景 | 命令 | URL 行为 |
|---|---|---|
| 单次发布 | npx pagecast publish "/abs/path/file.md" --json | 每次生成新 token |
| 持续目标进度 | npx pagecast goal publish "/abs/path/pagecast-goal.md" --json | 同 URL 原地更新 |
| 整站部署 | npx pagecast pages deploy "/abs/path/dist" --project <name> --json | 替换命名 Pages 项目 |
资料来源:plugin/skills/publish-report/SKILL.md 与 llms.txt。
多平台安装路径
plugin/README.md 列出了三种安装方式:Codex CLI/桌面版复制 .codex/skills/publish-report/ 到 ~/.codex/skills/;Claude Code 通过 /plugin marketplace add Amal-David/pagecast + /plugin install pagecast@pagecast 一键安装;其它 Agent Skills 兼容工具复制可移植版本即可。资料来源:plugin/README.md。
浏览器扩展(Chrome)
形态与权限
扩展在 Chrome Web Store 列表中以 "Pagecast — Local to Public" 命名,定位于开发者工具类。资料来源:extension/store/listing.md。其触发方式有两种:工具栏按钮点击,或在 file:// 页面右键菜单选择 "Publish to Pagecast"。资料来源:extension/store/listing.md 与 README.md。
扩展声明的权限是"最小且本地化"的:activeTab/tabs 用于读取当前标签页 URL 以识别 file:// 来源;127.0.0.1/localhost 用于把文件路径发给用户本机上的 Pagecast 服务;contextMenus 用于注册右键菜单;notifications 用于回显结果或报错。不收集任何用户数据,远程代码不加载——文件路径仅到达用户自己的本地回环服务,不会发送到任何远端。资料来源:extension/store/SUBMIT.md。
联动本地 App
扩展不是独立发布器,它依赖本机运行的 npx pagecast 进程:扩展把 file:///.../report.html 路径 POST 到本机 127.0.0.1:4173 的管理服务,Pagecast App 完成 Cloudflare 鉴权与 Pages 部署,再回传一个 https://pagecast.pages.dev/p/<token>/ 链接给扩展。资料来源:extension/store/listing.md 与 plugin/skills/publish-report/SKILL.md。同一文件重复发布时链接原地更新,旧链接可通过 npx pagecast 的 revoke 控制失效。
数据流总览
flowchart LR A[AI 代理<br/>写入 .html / .md] -->|PostToolUse Hook| B(Skill: publish-report) B -->|用户确认 Yes| C[npx pagecast publish --json] A2[浏览器扩展<br/>file:// 页面] -->|POST 本机 4173| C C --> D[(本地 .pagecast/ 数据目录)] D --> E[Cloudflare Pages 部署] E --> F[公网 pagecast.pages.dev 链接] F -->|反馈/分析 widget| G[Cloudflare Worker + KV]
资料来源:plugin/README.md、extension/store/listing.md 与 feedback/worker.js。
社区反馈与使用注意
社区中曾有用户提问"为什么选 Pages 而不是 Workers + Static Assets"——这是当前架构选型的明确信号:所有公开页面托管在 Cloudflare Pages 上,过期与密码保护由 Pages Function 在边缘强制执行(v0.1.6 的 Expiring URLs 即基于此),无需常驻机器即可让链接按计划失效。资料来源:plugin/skills/publish-report/SKILL.md(边缘执行说明)。
使用时的关键约束:
- 必须显式确认:代理和扩展都不得在用户未同意的情况下发布任何文件。资料来源:llms.txt 与 plugin/skills/publish-report/SKILL.md。
- 必须使用绝对路径:
npx pagecast publish要求绝对路径,相对路径需先基于 cwd 解析。资料来源:plugin/skills/publish-report/SKILL.md。 - 错误码含义:
401提示未完成 Cloudflare 登录;409表示存在多个 Cloudflare 账号,需通过--account显式选择。资料来源:llms.txt。 - 不要混用发布语义:
publish <file>产出新的/p/<token>/分享链接;publish site/pages deploy直接替换整个命名 Pages 项目的内容。资料来源:llms.txt 与 plugin/skills/publish-report/SKILL.md。 - Chrome 扩展需开启"Allow access to file URLs",否则无法读取本地文件页面。资料来源:extension/store/listing.md。
See Also
- 核心数据流与 Pages 部署:README.md
- Agent 命令总览与错误码:llms.txt
- 本地 Markdown 渲染与安全策略:src/markdown.js
- 反馈与分析 Worker:feedback/worker.js
- 管理服务与发布管线:src/server.js
安全模型、Cloudflare 部署与运维
Pagecast 是一款本地优先的发布工具,其设计目标是把本地 HTML/Markdown 文件转换为可分享的公共链接。围绕该目标,它将部署目标选定在 Cloudflare Pages 而不是 Workers + Static Assets。这一点由项目维护者在社区中被多次问及 (README.md)。
继续阅读本节完整说明和来源证据。
1. 概述与架构选型:为什么选择 Cloudflare Pages 而非 Workers
Pagecast 是一款本地优先的发布工具,其设计目标是把本地 HTML/Markdown 文件转换为可分享的公共链接。围绕该目标,它将部署目标选定在 Cloudflare Pages 而不是 Workers + Static Assets。这一点由项目维护者在社区中被多次问及 (README.md)。
选择 Pages 的关键原因与 Pages Functions 的能力直接相关:Pages Functions 可以和静态资源共存,并通过 _routes.json 把中间件限制在特定前缀下。这正是密码保护、过期链接等"边缘执行"特性的工程前提。资料来源:src/crypto.js 中 renderAuthMiddleware 与 renderRoutesJson 的职责划分即体现了这一点——前者生成 Pages Function 源,后者生成仅作用于 /p/<slug>/ 前缀的路由白名单,使得未受保护的站点保持纯静态。
下表总结了 Pagecast 与 Cloudflare 资源模型的对应关系:
| 组件 | Cloudflare 资源 | 作用 |
|---|---|---|
| 已发布页面 | Pages Project 静态资源 | 承载 /p/<token>/ 路径的 HTML/Markdown 内容 |
| 密码/过期中间件 | Pages Function (functions/_middleware.js) | 在边缘拦截访问,进行认证与过期判断 |
| 反馈统计 | Worker + KV (PAGECAST_FEEDBACK) | 聚合浏览量、表情反应与粗粒度访问者特征 |
| 部署触发 | 本地 CLI shell 调用 Wrangler | 复用官方部署 CLI,避免重复实现上传逻辑 |
2. 安全模型:边缘强制的密码保护与过期链接
Pagecast 的核心安全边界是"内容部署为明文,仅在边缘进行访问控制"。具体实现细节如下:
- PBKDF2 哈希:Node 端使用
node:crypto的pbkdf2Sync计算口令哈希,迭代次数为PBKDF2_ITERATIONS = 100000,摘要算法sha256,盐长 16 字节,导出密钥长 32 字节。资料来源:src/crypto.js。该参数刻意低于公开下载场景常用的 600k,因为哈希永远不会被作为静态资源暴露给攻击者,拉伸属于纵深防御而非主防线。 - 跨运行时一致性:Node 端使用 WebCrypto PBKDF2 重新计算并比较口令,确保与 Functions 中 WebCrypto 的结果一致。资料来源:src/crypto.js 中关于 cross-runtime parity 的注释,并被
test/crypto.test.js验证。 - 常时比较:使用
timingSafeEqual避免哈希比较时的侧信道。 - 过期链接(v0.1.6):链接可设为小时/1d/2d/7d/30d 或
Never,默认 30 天,可在安装级别配置并在每次发布时覆盖。过期检查在边缘由同一个 Pages Function 执行,因此即便用户机器离线,链接也会按时失效。资料来源:SECURITY.md 与 src/crypto.js 中描述的同一中间件。 - Markdown 渲染安全:发布页是公开的,渲染器从不透传原始 HTML——所有文本/代码段在发出前都会被转义;链接/图片 URL 经过
sanitizeUrl校验,仅放行允许的 scheme(如相对路径、片段、查询),其他 scheme(javascript:、data:、vbscript:、file:等)会被中和为#。资料来源:src/markdown.js 的escapeHtml/escapeAttribute/sanitizeUrl。
3. Cloudflare 部署流程
部署由本地 CLI 触发,最终通过 wrangler pages deploy 完成。Pagecast 在 src/server.js 的 createCloudflarePagesPublisher 中封装了站点目录组装、pages-site 与 pages-deploy 的工作树管理,以及超时(默认 180 秒)的 spawn 调用。资料来源:src/server.js。
CLI 层面提供两条发布路径(src/cli.js):
publish <file>—— 为单文件生成新的/p/<token>/分享链接。pages deploy <dir> --project <name>—— 将整个静态目录部署到指定 Pages 项目;省略--branch时默认main。直接站点部署会替换目标项目的内容。pages setup—— 一次性连接 Cloudflare 并准备项目。pages status/pages projects list—— 查询项目状态与列表。
flowchart LR
A[本地 HTML/Markdown] --> B[pagecast publish]
B --> C{需要保护?}
C -- 是 --> D[生成 _middleware.js]
C -- 否 --> E[纯静态产物]
D --> F[pages-site/p/<slug>/]
E --> F
F --> G[wrangler pages deploy]
G --> H[Cloudflare Pages]
H --> I{边缘拦截}
I -- 密码正确 / 未过期 --> J[返回内容]
I -- 失败 --> K[401 挑战]4. 反馈 Worker 与隐私
反馈功能由一个独立部署的小型 Worker 提供支持(feedback/worker.js)。其设计要点:
- 存储:使用单个 JSON 聚合对象,按 slug 写入 KV(绑定
PAGECAST_FEEDBACK,键stats:<slug>)。读写采用get → mutate → put模式。KV 不支持原子自增,因此在强并发下计数为尽力而为(best-effort),这对于浏览/反应统计是可接受的权衡,避免了引入 D1 的成本与复杂度。 - 反应白名单:
REACTIONS = ["👍", "❤️", "🎉", "🚀", "👀"],任何超出白名单的内容会被忽略,防止攻击者写入任意字符串。 - 隐私边界:仅存储粗粒度聚合信号——国家(来自
request.cf.country)、来源 HOST(非完整 URL)、设备类别(来自 UA)。无 IP、无 Cookie、无单访客记录、无 PII。
5. 扩展权限模型与运维
Chrome 扩展通过本地回环与运行中的 Pagecast 服务器通信(extension/store/SUBMIT.md)。其权限被刻意收窄:activeTab/tabs 用于检测可发布的 file:// 页面;contextMenus 用于右键入口;notifications 用于展示结果;主机权限 127.0.0.1/localhost 用于发送文件路径。扩展声明不收集或使用任何用户数据,所有 JS 均随包发布,无远程代码。
运维方面,llms.txt 总结了关键错误码的处理范式(llms.txt):
401:未连接 Cloudflare,需执行npx pagecast pages setup,或在应用中点击 Connect Cloudflare。409:存在多个 Cloudflare 账号,可通过--account <account-id>指定或在应用中选择。
SECURITY.md 列出的硬化路线图包括:私密/口令/过期链接、feedback destroy 拆解命令、API Token 鉴权(替代宽 OAuth)、Wrangler 与 npm 的固定/出处校验。资料来源:SECURITY.md。这与 v0.1.6 已落地的"过期链接"演进方向一致——每一项硬化都把更多控制权从信任用户操作转向由边缘强制。
See Also
- README.md — 项目总览与快速开始
- plugin/skills/publish-report/SKILL.md — 编码代理发布技能
- SECURITY.md — 安全策略与硬化路线图
来源:https://github.com/Amal-David/pagecast / 项目说明书
失败模式与踩坑日记
保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。
可能增加新用户试用和生产接入成本。
安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
假设不成立时,用户拿不到承诺的能力。
新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
Pitfall Log / 踩坑日志
项目:amal-david/pagecast
摘要:发现 8 个潜在踩坑项,其中 1 个为 high/blocking;最高优先级:安装坑 - 来源证据:Pages not Workers?。
1. 安装坑 · 来源证据:Pages not Workers?
- 严重度:high
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:Pages not Workers?
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 证据:community_evidence:github | https://github.com/Amal-David/pagecast/issues/1 | 来源类型 github_issue 暴露的待验证使用条件。
2. 配置坑 · 可能修改宿主 AI 配置
- 严重度:medium
- 证据强度:source_linked
- 发现:项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主,或安装命令涉及用户配置目录。
- 对用户的影响:安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
- 证据:capability.host_targets | https://news.ycombinator.com/item?id=48590505 | host_targets=claude_code, claude
3. 能力坑 · 能力判断依赖假设
- 严重度:medium
- 证据强度:source_linked
- 发现:README/documentation is current enough for a first validation pass.
- 对用户的影响:假设不成立时,用户拿不到承诺的能力。
- 证据:capability.assumptions | https://news.ycombinator.com/item?id=48590505 | README/documentation is current enough for a first validation pass.
4. 维护坑 · 维护活跃度未知
- 严重度:medium
- 证据强度:source_linked
- 发现:未记录 last_activity_observed。
- 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
- 证据:evidence.maintainer_signals | https://news.ycombinator.com/item?id=48590505 | last_activity_observed missing
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 证据:downstream_validation.risk_items | https://news.ycombinator.com/item?id=48590505 | no_demo; severity=medium
6. 安全/权限坑 · 存在评分风险
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:风险会影响是否适合普通用户安装。
- 证据:risks.scoring_risks | https://news.ycombinator.com/item?id=48590505 | no_demo; severity=medium
7. 维护坑 · issue/PR 响应质量未知
- 严重度:low
- 证据强度:source_linked
- 发现:issue_or_pr_quality=unknown。
- 对用户的影响:用户无法判断遇到问题后是否有人维护。
- 证据:evidence.maintainer_signals | https://news.ycombinator.com/item?id=48590505 | issue_or_pr_quality=unknown
8. 维护坑 · 发布节奏不明确
- 严重度:low
- 证据强度:source_linked
- 发现:release_recency=unknown。
- 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
- 证据:evidence.maintainer_signals | https://news.ycombinator.com/item?id=48590505 | release_recency=unknown
来源:Doramagic 发现、验证与编译记录