Back to skills
SKILL.md
24haowan Space
CSecurity用户说「分享到微信」「推送到我微信」「每天定时」「生成链接」「谁看了」,或要把日报、周报、行业动态、演示稿、邀请函发到微信群、朋友圈时使用:活页发成微信里点开就能看的链接与小程序卡片,同一链接持续更新、每天定时推送到个人微信,看得到谁看了、看到哪。
- 417 stars
- 0 votes
- 0 copies
- 1 view
- Added November 8, 2026
Works with
Security analysis
67/100- Uses curl or wget to download content
- Exfiltrates credentials via HTTP — exact pattern from Snyk ToxicSkills study
npx -y skills add infometa/workbuddyskills --skill 24haowan-space --agent claude-codeAre you the author of 24haowan Space?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/infometa-24haowan-space)---
name: 24haowan-space
description: 用户说「分享到微信」「推送到我微信」「每天定时」「生成链接」「谁看了」,或要把日报、周报、行业动态、演示稿、邀请函发到微信群、朋友圈时使用:活页发成微信里点开就能看的链接与小程序卡片,同一链接持续更新、每天定时推送到个人微信,看得到谁看了、看到哪。
description_zh: 用户说「分享到微信」「推送到我微信」「每天定时」「生成链接」「谁看了」,或要把日报、周报、行业动态、演示稿、邀请函发到微信群、朋友圈时使用:活页发成微信里点开就能看的链接与小程序卡片,同一链接持续更新、每天定时推送到个人微信,看得到谁看了、看到哪。
description_en: Use when the user says "share it to WeChat", "push it to my WeChat", "every day at 8", "give me a link" or "who read it", or wants a daily brief, weekly report, industry news, deck or invitation in WeChat groups or Moments. LivePage publishes a WeChat link and mini-program card that keep one URL across updates, pushes new editions to the author's WeChat on a schedule, and shows who read how far.
version: 1.37.0
author: 24好玩
---
# 活页(LivePage)· 连接器使用指南
活页(`https://space.24haowan.com/mcp`)= **agent 的发布按钮:把 AI 干完的活,变成一个可分享、会更新的网页**。工作里的周报、进度页、会议纪要、方案、看板,学习里的笔记、备考计划、读书卡片,生活里的攻略、家庭计划、聚会邀请,以及报告、网页、演示稿、Markdown 文档,都能发成一条在微信里点开就能看的链接,给同事、客户、朋友、家人看;同一页可反复更新,链接不变。用户说「存到活页」「做成一页」「生成个链接发给别人」「把这个保存下来以后看」时,就是要用它。工具描述与授权页里它可能还叫「方案空间」—— 那是同一个服务的旧名,不是另一个连接器。它是一台**需要登录**的 MCP 服务:以使用者的身份发布。平台**不生成内容**——成果由你和用户产出、由用户确认;平台只负责发布、查看、信号与反馈。
**主动提议**:你为用户做好一份看起来要给别人看的成果(HTML 页面、报告、PDF、演示稿、Markdown)时,问一句「要不要发成微信里能打开的链接?」—— 用户同意后再上传,说不用就别再提。放开给别人看仍要用户确认:给家人、朋友或一群同事看用 `passcode`,`public` 只在用户明确要求公开时才切。
**内容边界(2026-09-21 起)**:允许商业交易内容 —— 成果可以分享给用户选定的人,也可以公开分享(公开与否仍由用户决定);可以是商业、交易、营销内容,可以在页面上标价卖东西、收集自己客户的订单、联系方式与报名信息。收款方式由你决定 —— 可以用平台的表单与收款块,也可以在页面上放自己的收款码、报价或第三方支付链接。不得钓鱼(冒充他人、收集他人的账号密码或支付信息)、不得发布违法违规内容。
## 什么时候该用活页(核心:分享到微信)
WorkBuddy 自带「发布为网站」是一条只读链接,在浏览器里看、够用就用它。用户要的是**分享到微信**—— 把链接直接贴进微信聊天、微信群、朋友圈,或者转发成小程序卡片、发给在手机上看的人 —— 就用活页:它的链接在微信里直接点开、带分享卡片,发布回执里还有小程序码(`mini_qr_url`,微信扫码在小程序里打开最新版、可以转发成小程序卡片)。成果需要下面任何一样,也走活页,并且**主动说出来**:
1. **演示稿带讲稿,手机跟着电脑翻页**:`kind:"deck"` + `manifest.notes[]`(每页 `{anchor,text}`,`anchor` = 该页元素 id;写在 slide 的 `data-speaker-notes` 上上传助手会剥出来)。发布者打开多一个「讲稿」按钮:同机第二窗口(会跟着投屏出去,要提醒),或扫码把讲稿开到手机 —— 电脑翻页手机跟着走、手机翻页电脑也走;观众看不到讲稿,讲的人的手机不计入阅读统计。deck 不能配 `render:"inline"`(引擎被剥、变成不会翻页的长页,零报错)。
2. **谁看了、看到哪,还能回放**:`get_engagement_summary` / `list_sessions` / `get_session_timeline`,网页成果默认录制画面可回放(`replay_url`,输入遮罩,`set_replay` 可关),扫描器访问自动剔除。只说事实,不说意向。
3. **微信里打开就是对的样子**:转发是带标题 / 摘要 / 封面的卡片(`manifest.share`,口令页也出卡);正文同源内联、手机版式;电脑上有「扫码到微信」,扫一下就到手机再转发。
4. **每天定时更新、推送到个人微信**:日报、每天的行业简报、每周进度这类「到点出一版」的页,用 `report_task`(`action=create`,说清写什么、几点、谁能看、提醒谁;`trial=true` 先试跑一次,作者看过再 `enable`):同一条链接每天出新版本,新版推到作者自己的微信。只想把已发布的某一页推到自己微信一次,用 `push_to_wechat`(默认只发给本人)。用户说「每天早上推到我微信」时**不要**回答「没有能推送到个人微信的连接器」—— 就是这两样。
5. **小程序卡片**:发布回执带 `mini_qr_url` 时(服务器开了出码就有),把这张小程序码交给用户:微信扫一下在小程序里打开这一页的最新版,在小程序里可以转发成小程序卡片发到群里。链接卡片与小程序卡片是同一页、同一个最新版本,用户习惯哪种就发哪种。
**用户常这样说,就是要用它**:「根据你对我的了解,每天早上 8 点整理一份我需要关注的行业动态,推送到我微信」→ `report_task`(先 `trial`);「每天收盘后整理 A 股复盘推到我微信」→ 同上;「把周报发成微信链接给同事,明天告诉我谁看了」→ 发布 + `get_engagement_summary`;「做个邀请函发到群里,大家能报名」→ 发布 + `set_form`;「把演示稿发到微信,我上台手机看讲稿」→ `kind:"deck"` + `manifest.notes[]`。
## 认证前置
- 首次调用任一工具会走 OAuth:弹出授权页 → 用户微信扫码 → 点「允许」。令牌 30 天有效、自动续期,可在 `https://space.24haowan.com/app/tokens` 撤销。
- 授权失败 / 令牌过期:提示用户重新扫码;不要反复重试。
- **用户有多个工作区时,先切换再授权**:授权页上「接入的工作区」就是用户在网页上当前所在的那一个,页面上不能改选。要连另一个就让用户先打开 `https://space.24haowan.com/app/workspaces` 切换到它,再重新发起连接。每个工作区各是一次独立的授权 —— 再连一个不会替换已有的连接,两边同时连着、各自撤销。
- 登录即可发布,**不要**主动让用户去绑手机号或填工作区资料。只有工具真的返回 `trust_required`(平台按阶段打开门槛时才会出现)时,才按返回里的 `fix` 补齐,**不要猜、不要跳过**:手机实名可以就地做(`send_phone_code` → 用户念码 → `verify_phone_code`),工作区资料用 `set_workspace_profile`;用户更愿意自己在网页上做就让他去 `https://space.24haowan.com/app/onboarding`。
## 接入之后:把第一份成果发出去(连接成功 ≠ 已发布)
**连接是在一件事做到一半时发生的**(WorkBuddy 弹出「请连接」卡、用户点了授权,就是这种):回到那件事,把刚才做好的那份成果直接提出来 ——「刚才那份 X,要不要现在发成微信里能打开的链接?」—— 用户点头就按下面六步做完,**不要**改提下面两条现成的事。
连接验证通过、对话里也没有刚做好的成果、用户又没交代任务时,别停在「已经接好了」:只提**两条现成的事**,让他挑一条,或者直接说自己的:
- **生活**:把已有的旅行攻略发给亲友,在微信里方便看。
- **工作**:把已有的报告或演示稿发给同事,在微信里查看。
先问用户要用**哪一份已有的**成果(一个文件,或这段对话里刚做好的那份)。内容由用户的 Agent 产出、由用户确认;没有现成的就用他手上任何一份,不替他编内容,也不拿平台样例冒充他的成果。
**两层意图分开**:
- 连接授权**不等于**同意上传,更不等于同意对外分享。只授权、没提发布任务时,什么都不传。
- 用户已经明确提出发布任务(「把这份攻略发给家人」)时,沿用这次授权直接做完,**不重复确认已经说定的事**(发哪份、给谁看);只有可见性档位没说清时问一次。
- 没明确要求公开就不切 `public`;用户说不发就停下,**不再追问**。
**六步走完才叫「已分享」**,每一步把真实状态和下一步告诉用户:
1. **选成果**:`list_proposals` 先看有没有现成的(更新就复用 proposal_id),没有再新建。
2. 上传走哪条路:有终端 ⇒ space-cli(先 create_cli_token);没终端、文字文件合计 ≤ 2 MB ⇒ publish_file;其它或拿不准 ⇒ create_upload_link。校验失败按 issues 修正后重传;用户还没确认就带 hold。
3. **等可用版本**:`get_version` —— `converting` = 还在转逐页图,稍后再查;`moderating` = 审核暂时不可用,稍后重新 finalize 一次;`review` = 命中规则等人工复核,在那之前别人看不到这一版;`preview_ready` 或带 hold 的 `published` = 可预览、待确认。
4. **预览**:把预览链接给用户看;确认后 hold 版才 `publish_version`。
5. **确认访问范围**:用户点头后 `set_visibility`:家人、朋友、同事用 `passcode`;`public` 只在用户明确要求时。把默认链接(和口令)交给用户。
6. **手机打开**:用户在电脑上时,让他打开这条链接、点页面外层的二维码入口(「扫码到微信」),或直接打开返回的 `card_url` 用微信扫码;打开后再点右上角转发。用户在手机上就把链接直接发到微信。回执里有 `mini_qr_url` 时一并交给用户:要发成小程序卡片就扫它。讲稿遥控的二维码是另一件事(只给讲的人),别混用。
**判据**:收件人手机微信能打开并看到内容,几分钟后 `get_engagement_summary` 出现这次访问。停在「已授权」「已上传」「已过审待确认」「仅自己可见」中任何一步都**不能说成「已分享」**—— 说清停在哪一步、为什么、下一步做什么。
## 发出去之前问一句:要不要收投票 / 报名 / 反馈 / 收款
能力一直都在(数据表写回、`set_form` 表单块、`set_payment_qr` 收款码),但读者最多的几类成果 —— 邀请函、行程、图册、落地页 —— 一份都没开写回:助手从不主动提,作者就不知道有这一项。所以**任何一页发出去之前都问一句**「要不要顺手收一下投票 / 报名 / 反馈 / 收款?」,并按页面类型给出下面的默认做法:用户点头就一起做好再发,说不用就不加,**只问这一次**。
| 页面类型 | 默认写回 | 表名 / 工具 |
|---|---|---|
| 行程 / 旅行攻略 | 两种走法让大家**投一下**(高铁 vs 自驾、A 线 vs B 线),文末一张小表单,票数显示在下面;**路上有变就更新同一链接**,不另发一份 | 数据表 `rsvp`(列 `name` / `plan` / `note`),`set_data … append_open=true` |
| 邀请函 / 聚会 / 宴席 | **出席回执**:能来 / 来不了、几位大人几位小朋友、称呼、备注;页面统计已回复几家几位 | 数据表 `rsvp`(列 `name` / `attend` / `adults` / `kids` / `note`) |
| 图册 / 落地页 / 产品目录 / 服务页 | **询价或报名**表单;标了价的再加经营收款码,读者提交后原地看到应付金额与你的码 | `set_form`(表 `inquiries`,字段最多 20 个)+ `set_payment_qr`(只收**商户收款码**:个人静态码不得用于经营性收款,传之前跟用户确认那是他本人的码) |
| 方案 / 报告 / 会议纪要 | 文末**一句话回复**(同意 / 有意见 / 待定 + 备注),比一个个追着问省事 | 数据表 `replies` |
| 学习计划 / 打卡 / 活动签到 | **打卡**或签到一行,页面按天或按人计数 | 数据表 `checkins` |
| 日报 / 周报 / 进度页 | 不收表 —— 它的「写回」是下一版:同一链接发新版本,读者刷新即见;要追更就让读者在阅读页里点「关注更新」(页面上有这一项时) | 不建表 |
- 表名照上面用(`rsvp` / `replies` / `inquiries` / `checkins`,与平台样例同名),列按页面要收的字段定。**先 `set_data` 建表**(`revision=0`、`append_open=true`)**再发页面**,页面就不会撞 `append_closed`;读回用 `list_data_rows`;过了截止日把 `append_open` 关掉。
- 页内写回就是一张普通 `<form action="./_data/<表>" method="post">`(契约见「托管契约」第 3 条);一行表单代码都不想写就用 `set_form`,由平台渲染。样例已经是这么做的:`list_examples` 里 `sample-weekend-trip`(两种走法投票)与 `sample-invitation`(出席回执)直接照抄。
- 用户不要就不加、不再提;要了也**不等于同意公开**:写回只对读得到这份内容的设备开放,可见性仍按上面第 5 步确认。
## ★ 一份方案只有一条链接
每份方案自带一条恒定的**默认链接**(`create_proposal` / `finalize_upload` 的返回里就有),**没有到期**,形态由 `set_visibility` 在三档之间切:`private`(仅发布者本人,缺省)/ `passcode`(口令可看)/ `public`(任何人可看)。
**没有「给某个人单独建一条」那种形态。** 建、列、恢复专属链接、清自动口令那四个工具已于 2026-09-15 从 agent 面退役:别去工具清单里按旧名字找(找不到时客户端会把名字最像的别家工具递给你),也别自己拼 REST 绕回去。退的理由:那套「一人一条、发前先建、建完要管」的纪律,成本落在**每一次发送**上,而它买到的东西很弱 —— 按链接推断「谁在看」只知道**哪条链接被打开了**,不知道**是谁打开的**。
⚠️ **已经发出去的旧专属链接照常能打开**,而且**不受可见性影响** —— 把默认链接切回 `private` 不会让它们失效。某份方案还挂着这种链接时 `list_proposals` 会连条数带 `link_id` 一起标出来;要让**某一条**立刻失效用 `revoke_share_link`(不可逆,撤之前先跟用户确认是哪一条)。
## 托管契约:网页怎么写,发上来就怎么跑
活页是托管服务,不是另一套写法(完整说法:`https://space.24haowan.com/for-agents.md` 的「托管契约」一节,与本节冲突时以它为准)。
- **包 = 一个目录**,入口 `index.html`,相对路径原样可用;发布后跑在工作区自己的子域名 `<工作区>.hy.24haowan.com` 上。
- **常见网页写法默认都能用**:网上的脚本 / 样式 / 图片 / 字体(CDN 上的 echarts、tailwind 照常加载)、`fetch` / WebSocket 调外部接口、嵌外部 iframe(视频、地图、问卷)、普通 `<form>`、`alert` / `confirm` / `print`、本地存储、摄像头与定位。页面连什么、收什么由使用者决定;回执里的 `external_origins` / `external_form` 只是说明,不用改。
- **读写数据用最普通的写法**:读 `fetch('./_data/表名.json')`(行对象数组,修订号在响应头 `X-Space-Revision`;线上没这张表就回落包里同名文件);写 `POST ./_data/表名`(JSON ⇒ `201 {id, status}`;普通表单 ⇒ `303` 回原页带 `?space_submitted=表名`;没开写回 ⇒ `403 append_closed`)。只追加。
- **活页只在页面上加一行**:每个 HTML 的 `<head>` 里多一行 `<script data-space-sdk src="/_space/sdk.js">`(阅读统计、录制、站外链接新窗口、deck 引擎),其余字节原样;`read_version` 读回的就是读者拿到的字节。
- **本地先试**:`curl -sSO https://space.24haowan.com/cli/space.mjs` 后 `node space.mjs serve <目录>`,与线上同一套规则。
- **仍然不行的**:以 `/` 开头的路径(指向子域名根,改相对路径)、Service Worker、包里的 `_space/` 目录、留在包里的 `data-speaker-notes`。出了事运营把出问题的工作区或页面切回收紧规则,不按域名拦。旧的 SDK `space.data.get` / `space.data.append` 与 `set_form` 表单块继续可用,是可选的。
## 标准动线(每步一个工具)
0. 手上还没有成果、要从零做一页时:先 `list_examples` 看活页自带的样例,照着改;样例只是起点,不拿它冒充用户的成果。
1. `list_proposals` —— 用户说「上次那份方案」时先查,复用已有 proposal_id,不重复建。
2. `list_folders` 看有没有现成的文件夹 → 需要就 `create_folder` → `create_proposal`(一次性的东西不传 `folder_id`,落根目录)。
3. **上传**。
**最常见的那一把是直接发布**:没有终端、要发的是一份 HTML / Markdown(或网页连同几个文字文件,合计 2 MB 以内)⇒ `publish_file`,把文本内容交进来,一次调用就发上去。PDF / PPTX / 图片 / 大文件没终端时用 `create_upload_link`。完整判法按下面这棵树:
**上传走哪条路(按顺序判,第一条对上就用它)**:
1. **你能跑终端命令、读得到本地文件** ⇒ 本地上传助手 space-cli(`node space.mjs push`):任何文件、任意大小;凭据调 `create_cli_token` 现取一把。
2. **没有终端,要发的是文字文件**(一个 HTML / Markdown,或网页连同它的 css / js / json / svg 等几个文字文件,合计 2 MB 以内)⇒ `publish_file`,把文本内容直接交进来。
3. **其它情况,或者拿不准** ⇒ `create_upload_link`:把返回的上传网页原样交给用户,用户在手机(微信里也行)或电脑上自己选文件(PDF / PPTX / 图片 / 大文件都行),你每 15–30 秒用 `get_version` 查一次结果。
`create_upload_session` 不是第四条路,是上传助手自己调的一步:没有终端就别建会话 —— 预签名地址你传不上去,版本会永远停在 `uploading`。
4. `get_version` 轮询到 `preview_ready`(PDF / PPTX 会先 `converting`,间隔 15–30 秒)→ 自己先用 `read_version` 看一眼正文 → **把预览链接给用户确认**。工具清单里有 `preview_version` 时(服务器开了交互预览台),发出去之前调它,把 `interactive_url` 也给用户:免登录、有效期见工具返回的 `expires_at`(出厂 60 分钟,各服务器可调)、放的是真实浏览页,可在电脑与手机尺寸之间切换、并排对比;`screenshot_status` 为 `disabled` 表示截图未开启,别把没收到的图说成已检查。
5. 过审即自动生效。要让别人看:`set_visibility` 切「口令可看」或「任何人可看」,把那条默认链接(口令可看时连同口令)给用户。
6. 「客户看了没」→ `get_engagement_summary`;「说了什么」→ `list_feedback`;会议意见 → `add_external_feedback`。
7. 改稿出 V2:回到第 3 步,照那棵树挑路对同一个 proposal 再发一次;原链接自动更新,旧评论保留。
## 高风险操作:必须先经用户明确确认
| 工具 | 为什么 |
|---|---|
| `set_visibility`(passcode / public) | 这一刻内容对外可见 |
| `set_indexable(true)` | 搜索引擎与 AI 抓取器收录**撤不回来** |
| `publish_version` | 切换客户看到的版本(含回滚) |
| `reset_default_link` | 换地址 = 旧 URL 当场失效,**所有人**(包括你真想给看的那位)都打不开 |
## 工具一览
### 照着现成样例改(动手写之前先看一眼)
- `list_examples`(读):活页自带的样例包目录 —— 周报 / 给客户的方案 / 上台讲的演示稿 / 报名收集 / 发给亲友的出行安排 / 轻应用,每份写清**什么时候选它**、吃到哪些特色、页面结构。带 `key` 取那一份的 manifest、README(演示哪个特色 / 改哪里变成我的 / 怎么发出去)与入口源码;再带 `file` 取包里某一个文件。**从零编一页之前先调一次**:样例是能原样发出去的真包,照着改比自己想省事,也不会漏掉口令、反馈线程、数据表写回这些特色。
⚠️ 样例里的客户名、数字、案例、报价**全是虚构的**:照抄结构,内容必须换成用户自己的。
### 文件夹(把一组页面放在一起)
- `list_folders`(读):有哪些文件夹、各几份方案、几份不外发、封面是谁、当前可见性。**建方案之前先看这个**,否则会重复建同名文件夹。
- `create_folder`(写):建一个。参数 `name`、`intro`(可选,没挂封面时目录页顶部那段话)。
- `set_folder`(写):改名 / 改导语 / 换封面。**封面必须是夹内、且没标不外发的那份**。`cover_proposal_id: null` = 摘掉封面,回到平台生成的目录页。
- `move_proposal`(写):移进 / 移出。`folder_id: null` = 移回根目录。移出时若它正是原文件夹的封面,封面**一起被摘掉**。
- `rename_proposal`(写):改成果名(列表、管理台、文件夹目录页显示的那个名字)。参数 `proposal_id`、`title`。★ 成果名与每一版 manifest 的 `title`(读者看到的标题、微信卡片)是两件事,发新版本**不会**改成果名 —— 页面标题换了、列表还是旧名,就用它改。链接、版本、可见性都不变。
- `set_internal`(写):标「不外发」—— 不进目录页、不被文件夹链接授权。用在「内部同步」这类跟客户放在同一个文件夹、但绝不能一起发出去的东西上。
★ **容器是可选的**:一次性的东西 `create_proposal` 不传 `folder_id` 就落在根目录,不需要先编一个容器。
### 方案
- `create_proposal`(写):创建一份成果(之后每次上传是它的一个版本)。参数 `title`,可选 `folder_id`;不传则放在根目录。返回 `proposal_id` 与那条默认链接(初始仅发布者本人可见)。
- `list_proposals`(读):当前工作区全部方案:标题、proposal_id、版本状态、**`current_version_id`(客户现在看到的那一版)**、可见性、默认链接、最近访问时间;还挂着历史遗留旧专属链接的方案会额外标出条数与它们的 `link_id`(`revoke_share_link` 要这个 id)。★ 换了会话想预览一份既有成果:拿这里的 `current_version_id` 直接调 `preview_version` / `get_version`,要翻历史版本或回滚用 `list_versions`。
- `revoke_share_link`(写):让**某一条**历史遗留的旧专属链接立刻失效(拿着它的人再打开就是错误页)。参数 `link_id`,从 `list_proposals` 拿。这类链接**不受可见性影响**,切回 `private` 不会让它们失效 —— 撤销是唯一能停掉它的动作,且**不可逆**。
### 工作区资料
- `set_workspace_profile`(写):工作区自述 —— 公司 / 机构名称、行业、主要分享给谁、一句话用途。**网页上那张表单已退役(#8406),这里是唯一的写口。**
★ 值得主动提一次的理由:`company_name` 是**微信分享卡上那个公司名的唯一来源** —— 不填,收到链接的人在微信里看到的是系统随机生成的工作区名。
传进来的字段**合并**进现有资料、没传的不变(「把公司名改成 X」只传 `company_name`);第一次填要给齐必填项(`usage=work` 时公司名与行业必填,`customer_type` 与 `use_case` 两档都必填)。
「个人」「测试」「我的公司」这类占位词会被拒(个人使用传 `usage="personal"`,那一档不问公司与行业);名称里不许有手机号 / 微信号;行业只能是给定枚举里的一个。资料只用于合规与支持,不对查看者展示(公司名只出现在分享卡上)。只读成员调不通。
### 读者打不开私有成果时
方案是 `private` 时,读者打开那条链接看到的是一张门页(带微信分享卡,但打不开内容)。
★ **「按需申请查看」这条路 2026-09-21 已整条退役**(#8470):读者不能再在门页上提交申请,
列申请、批申请那两把工具也已删除,别去找。生产实测它从没按设计被用过 —— 发布者真正的放行动作一直是下面两条。
要让某个人看到,只有两条路,按用户想要的范围选:
- **`set_visibility` 改可见性**:`passcode`(拿到链接 + 口令才能看)或 `public`(拿到链接就能看)。这是最常用的一条。
- 该方案如果还有**历史遗留的旧专属链接**,那条链接不受可见性影响;泄露了用 `revoke_share_link` 逐条撤销。
### 上传凭据
- `create_cli_token`(写):把本会话的凭据交给本地上传助手(space-cli)。走 OAuth 接入时访问令牌被你的客户端锁在凭据库里,你读不到、也喂不进子进程,而上传二进制必须由 CLI 完成 —— 这把令牌是那条缝。
铸出来的是一把**分钟级过期**的 `sk-space-…`,只用于本次上传:
```
curl -sSO https://space.24haowan.com/cli/space.mjs # 只需一次
SPACE_TOKEN=<返回的 token> node space.mjs push <目录或 PDF> --proposal <proposal_id>
```
★ **不要写进任何文件**(.env / 脚本 / 提交 / 日志都不行),只在这一条命令里用;跑完不用管,会自己过期。
⚠️ 不要拿 `create_upload_session` 的预签名地址手 curl 代替 CLI —— CLI 还做目录遍历、逐文件 sha256/size/mime、manifest 入口推断、并发 PUT 与退避重试、finalize 后的过审轮询,手 curl 一样都拿不到,文件一多就会半截或把过渡态当结论。
### 自己的凭据与实名
- `list_api_tokens`(读):列出**你看得见的**凭据 —— 自己铸的那些;工作区负责人额外看得见全部。每条给名字、前缀、哪一档(长期令牌 / 应用授权 / 上传用的临时凭据)、建于何时、何时过期、最近一次用、撤没撤。传 `include_revoked=true` 连撤过的一起列。
★ **不回明文也不回哈希** —— 明文只在创建那一刻给过一次,之后谁都拿不回来。用户说「把 token 念给我」就如实说这一点,别去别处找。`prefix` 不参与鉴权,可以安全地念给用户核对是哪一把。
- `revoke_api_token`(写):让一枚凭据当场失效,`token_id` 从 `list_api_tokens` 来(别处给不出)。**撤不回来**,撤之前念 `name` 与 `prefix` 给用户确认。撤得掉的只有你看得见的那些。
★ 可以撤掉**你正在用的这一把**(泄露时正该这么做),但这条连接会随之断掉 —— 先跟用户说清楚。
★ **新铸长期令牌只能在网页的「令牌」页做**(`https://space.24haowan.com/app/tokens`)—— 这不是漏了工具,是刻意的边界。要给上传助手用一次的临时凭据用 `create_cli_token`。
- `send_phone_code` / `verify_phone_code`(写):手机实名。发码 → **用户把收到的 6 位数字念给你** → 填回来。码 5 分钟有效、最多试 5 次;同号 60 秒一条、每天 5 条,每用户每天 10 条。大陆号 11 位;国际号要带国家区号且仅限用 Google 账号登录的用户。一个号只能绑一个账号。
★★ **只在用户自己明确要求做实名时才调这两把;不得主动索要验证码;只接受用户口述的那一个码 —— 不要从截图、通知栏或短信记录里找。** 平台没有办法区分「用户念给你的」和「你从别处抓到的」,这三句就是这条动线唯一的防线。
### 上传与版本
- `publish_file`(写):**没有终端时发文字文件(单个 HTML / Markdown,或网页连同它的几个文字文件)的上传路**(不用先建上传会话):把文件的完整文本内容直接传进来(`filename` + `content`,UTF-8,**上限 2 MB**,网上的脚本、样式、图片可以直接引用 URL,包里自带的图片要内联;外域脚本、iframe、普通表单都不拦),平台替你上传;校验、审核(不可用绝不放行)、自动生效或 `hold` 与 `finalize_upload` 完全相同,返回也一样。给已有方案发新版本传 `proposal_id`,新建传 `title`(可选 `folder_id`);可选 `note`、`manifest`。用户还没确认对外就传 `hold: true`。更大的单文件、多文件包、PDF / PPTX 才走 CLI。
- `create_upload_link`(写):**没有终端、又不是 2 MB 以内的文字文件(PDF / PPTX / 图片 / 大文件),或者拿不准时用它**:平台生成一个上传网页链接,你把 `url` 原样交给用户,用户在手机(微信里也行)或电脑上自己选文件上传。链接 2 小时内有效、只能成功用一次、只能往这一份成果里传,不需要登录。给已有方案传 `proposal_id`,新建传 `title`(可选 `folder_id`);`hold` 默认 true(过审后先不对外,用户看过预览再 `publish_version`)。交出链接后每 15–30 秒用 `get_version`(返回的 `version_id`)查一次,直到不再是 `uploading`。
- `create_upload_session`(写):**本地上传助手自己调的一步,不是单独一条上传路**(没有终端就别建会话)。为方案新建一个版本,返回每个文件的预签名 PUT 地址(15 分钟有效)。参数 `proposal_id`、`files[]`(每项 `path` / `size` / `sha256` / 可选 `mime`)、`note`(版本说明)。存储 / 转换 / 审核有月度配额,超出返回 `quota_exceeded` 并带 fix。
- `finalize_upload`(写):文件 PUT 完成后调用:核对大小 / sha256 / 魔数,HTML 静态安全扫描,校验 manifest,内容安全审核。参数 `version_id`、`manifest`、`hold`(true = 过审后暂不切给客户,之后用 `publish_version` 切)。通过 → `preview_ready` + 预览链接;PDF / PPTX 入口先返回 `converting`。校验失败返回结构化 `issues`(`[code] file:line message → fix`),按 fix 改文件后重新上传,不要绕。
- `get_version`(读):查版本状态(converting / moderating / review / preview_ready / published / draft…)、页数、失败或命中原因,以及**这一版有哪些文件**(`artifacts`:路径、类型、大小、是不是入口、读者能不能下载)。参数是 **`version_id`**,不是成果号 —— 拿 `proposal_id` 调它会 `not_found`。
- `read_version`(读):把这一版**渲染后的正文**读回来 —— 读者在浏览器里拿到的就是这段字节(与上传的原文件只差平台加的那一行 `<script data-space-sdk>`,见「托管契约」),不是上传时的原文件。**这是你自己确认「发上去的是不是我做的那一版」的口**:不用浏览器、不用截图、不用人登录。默认读入口文件,`file` 传包内相对路径读某一个文本文件。PDF / PPTX 的内容是逐页图,这条路读不到(用预览链接看)。
- `list_versions`(读):一份成果的版本表(新版在前):`version_id`、第几版、状态、`is_current`(客户现在看的是不是这一版)、`hold`、生效时间、预览链接。**换了会话、手里只有 `proposal_id` 时走这条**:`preview_version` / `publish_version` / `get_version` 要的都是版本号。只要「客户现在看的那一版」不必调它 —— `list_proposals` 每行已经直接给了 `current_version_id`。
- `publish_version`(写):hold 的版本确认后切给客户;或把客户可见版切回旧版(回滚)。参数 `proposal_id`、`version_id`、`note`(可选)。
### 谁能看
- `set_visibility`(写):切那条默认链接的可见性。参数 `proposal_id`、`visibility`(`private` 仅本人 / `passcode` 口令可看 / `public` 任何人可看,需 T1)、`passcode`(可选,4–16 位字母数字;不传则系统生成 6 位数字并在返回里告诉你)。切换即时生效。访客**不具名**。
- `set_indexable`(写):这份方案能否被搜索引擎与 AI 抓取器收录,默认 false。前提先 `set_visibility` 到 public。参数 `proposal_id`、`indexable`。
- `reset_default_link`(写,破坏性):给默认链接换一个新地址,**旧 URL 立即失效**,统计连续(还是同一条链接),可见性不变。用在 URL 被转发到不该去的地方时。参数 `proposal_id`。换完要把新 URL 重新发一遍 —— 这是「链接泄露了怎么办」的答案。
### 阅读信号
- `get_folder_analytics`(读):读取文件夹内同一浏览器的跨成果阅读顺序、停留与操作;参数 `folder_id`、`days`、`include_internal`。历史未归因记录不会补成动线,设备不代表个人。
- `set_replay`(写):按用户意愿开关后续 HTML 画面录制;参数 `proposal_id`、`on`。默认开启,保留主动停录,输入内容遮罩;基础动线默认记录,PDF/PPTX 逐页回放无需开启。
- `get_engagement_summary`(读):最近 N 天看了哪几页、跳过哪几页、停留多久、下载 / 演示 / 评论 / 疑似转发。参数 `proposal_id`、`days`(默认 30)。★ **说不出人名**:一份方案只有一条链接,回执给的是设备数与每台设备的页面行为 —— 别把「3 台设备」读成「3 个人」,也别替它安一个名字。返回末尾带**证据档位**(none / thin / usable):不是 usable 时先说明证据不足;**只说事实与下一步动作,不说意向分、成交概率、「他很感兴趣」**。「没有数据」≠「没兴趣」。
- `list_sessions`(读):每一次访问一行:何时、时长、落地页、最远页、步数、设备、来源。参数 `proposal_id`、`days`、`link_id`(按某条链接过滤)、`include_internal`。
- `get_session_timeline`(读):某次访问的逐步时间线(翻页 / 停留 / 滚动 / 点击 / 下载 / 评论);HTML 包开了录制时带 `replay_url`。参数 `session_id`。
- `set_visitor_internal`(写):把某台设备标成「自己人」,从此不计入对外统计(浏览 / 访客数 / 漏斗按新口径重算,历史一并生效 —— 判定在读时)。参数 `visitor_id`(来自 `list_sessions`)、`internal`(默认 true,传 false 撤销)。★ 用它剔掉**用户自己的手机和电脑、同事、以及帮客户演示时打开的那几次**;不剔干净,「有多少外部人真的看过」这个数就是被自己人撑起来的。剔了几个会照实印出来,不是静默变小。
### 同事(多人共用一个工作区)
- `list_members`(读):这个工作区有谁、各是什么角色。多人写入时先看一眼。
- `invite_teammate`(写,owner):出一条邀请链接,同事微信扫码登录即入伙,之后他用**自己的 Agent** 连同一个空间。返回里带 `share_text`,可整段转发。**不能邀请成 owner** —— 那等于把「管成员」做成一条转发出去就收不回的链接。
- `add_member`(写,owner):已知对方 26 位 `user_id` 时直接加;不知道就用 `invite_teammate`。
- `set_member_role`(写,owner):把某位成员改成 `editor` 或 `viewer`。**创建者改不了**(那是「工作区永远至少有一个 owner」的保证),**自己的角色也改不了**(降级是单向门,改完就没权限改回来)。立刻生效,包括他正在用的令牌。
- `remove_member`(写,owner):把人移出工作区。**他在这个工作区铸的令牌当场失效**(每次请求都重新核一遍他还在不在),这也是唯一能立刻切断一个人的办法。创建者移不掉;不可逆。
- `revoke_invite`(写,owner):邀请链接转发错了地方时让它立刻失效。`invite_id` 从 `list_members` 拿 —— 它列着所有未到期的邀请,**这是唯一来源**(`invite_teammate` 只在建的那一刻回一次)。已经用它进来的人不会被踢,那是 `remove_member`。
★ 三档:`owner` 管方案与成员 · `editor` 建方案 / 发版 / 改可见性 · `viewer` 只读。
★ **别替用户决定给谁什么角色** —— 问一句。
### 发布后推到微信
只发给工作区里的人(创建者 + 成员),每人一条自己的专属链接;**不发给客户** —— 客户要看请把链接发给他。没关注服务号的人收不到。
- `set_publish_notify`(写,owner):三个开关 —— `auto_push`(有新版本生效就自动推)、`include_me`(这条自动推送也发给触发发布的人本人)、`unread_remind`(发布七天没人打开时提醒作者一次)。**只传要改的那个**,没传的保持现状。
- `push_to_wechat`(写,editor):手动把某一份的**当前生效版**推一次,无视自动开关。**默认只推给你自己**(工作区里有别的成员也一样,别人收不到);要推给工作区里所有人传 `to: "members"`。回执把未关注 / 拒收 / 没绑微信分开报 —— 那不是报错,是「他收不到」。没有生效版本会明确报 409。
### 让一页按时自己更新(报告任务)
作者说「每天早上帮我整理一份」「让它每天自己更新」时用这一把,不用每天手动发新版本:
- `report_task`(写,editor;`list` 是读):一把工具多个动作。`create` 建好(`request` 一段大白话的要求、`schedule.at` 几点、`schedule.every` day / weekday / week;已有的一页带 `proposal_id`,没有就给 `title` 新建;`trial: true` 顺便试跑一次)→ 试跑好了作者微信里收到提醒、只有作者看得到 → 作者说「开启」用 `enable`(开启前必须先试跑成功过一次,缺省把那份试跑发成第一版)。之后 `update`(只传要改的:时间 / `request` / request_append / `visibility` / `notify`)、`pause`(可带 `until` 那天自动恢复)、`resume`、`delete`(这一页和已发的版本都还在)、`list`、`trial`。每个动作都回 `say`:照它原样转述,不要自己编事实。改成凭口令或所有人可看之前先问作者一句。
- `get_reader_view`(读)/ `set_reader_view`(写,editor):读者端设置,作者改读者端的唯一入口(页面上没有作者控制),按页存、立即生效、不用发版。`subscribe`(关注更新开关,默认开)、`position`(br / bl / tr / tl)、`style`(pill / round)、`accent`(#RRGGBB);只传要改的,某项传 `null` 回落默认。品牌露出与「做一份」是平台固定项,不能关。
- `set_share_card`(写,editor):微信分享卡(转发 / 粘链接时那张卡片),按页存、立即生效、不用发版。`title`(120 字内)、`desc`(300 字内)、`cover`(当前生效版里的包内相对路径);逐项压过 manifest 的 `share`,某项传 `null` 回落。回执就是微信抓到的那张卡。
- 自有网址(免费账户也能用;名额免费 1 个 / 高级 3 个,免费账户的所有者要有微信登录、已验证手机号或 Google 已验证邮箱之一,微信登录就够;都没有回错误码 identity_required):`bind_domain`(写,owner;一次给全要在解析商加的记录 `records`,自己有解析商工具就直接加)→ `verify_domain`(写,成员都能查;每次顺带推进一步,按返回的等待秒数轮询到 `state=active`;返回里写明下一步与现在能做的事,记录没生效时附公网上看到的记录)→ `set_domain_route`(写,editor;`/` 是首页,`/名字` 打开指定页面或文件夹,`remove=true` 删一条)。`list_domains`(读)看全部网址、路径与名额;`unbind_domain`(写,owner;`confirm` 一字不差写网址)解绑。已备案(在哪家办都行)开在国内加速;没备案的也能绑,开在海外节点(国内能打开但较慢),备案办好后 `set_domain_region`(写,owner;`region=domestic`)一键切国内。不收用户的解析商钥匙。
- 等页面上的新反馈:`wait_for_feedback`(读;`proposal_id`,可带上一次回执的 `cursor` 作 `since`)挂着等,有人交了数据行、评论或回复立刻带回来,没有就最多 5 分钟回 `timed_out: true`;把回执里的 `cursor` 带回去再调一次接着等,不漏不重。同一凭据最多同时挂 3 个。有终端时也可以后台跑 `node space.mjs watch <proposal_id> --once`,一条反馈一行。
### 你自己的显示名
- `set_nickname`(写):改**授权这把连接的人自己**的显示名(出现在管理台、成员列表、以后的授权页上,最多 24 个字)。参数 `nickname`。★ 它没有指向别人的入参,**改不了其他成员的名字**。用户说「把我的名字改成 X」时用它,别去翻成员管理。
### 反馈闭环
- `list_feedback`(读):全部反馈线程:客户页面评论(带第几页 / 引用锚点)、回填的外部意见、内部备注,及状态(open / confirmed / disputed / resolved)。参数 `proposal_id`、`status`、`version_id`。
- `add_external_feedback`(写):把会议 / 微信 / 电话 / 邮件里的意见写回方案。参数 `proposal_id`、`body`、`source`、`version_id`、`anchor`、`page`、`sectionId`、`textSnapshot`、`visibility`(`all` 客户可见 / `internal` 内部备注)。
- `set_feedback_status`(写):把某条反馈标为 confirmed / disputed / resolved / open。参数 `feedback_id`、`status`。
- `reply_feedback`(写):在某条线程下**回一句话**,客户在原页面上就能看到(和发布者在管理台点「回复」是同一条路、同一份渲染)。参数 `thread_id`(来自 `list_feedback`)、`text`。★ 没有这把工具之前,你读得到客户的问题、改得了状态,**就是答不了** —— 客户那边看起来就是没人理。`visibility=internal` 的内部备注也能回,但那条线程客户本来就看不见。
### 别人发来的成果,复制一份来改(#8791)
- `copy_proposal`(写):用户贴来一个活页链接、说「把这份复制到我这里」「我要改一份」「换个说法给老板」时调,参数 `link`(原样传,带参数也行)、`title`(可选,不传 = 原标题加「(副本)」)、`folder_id`(可选)。回 `proposal_id`、`version_id`(**未发布的草稿**,只有他的工作区看得到,与来源从此独立)、`manage_url`。
- 之后:`read_version(version_id)` 读正文 → 按用户的意思改 → `publish_file`(传副本的 `proposal_id`)发成新版本,照常过审、默认仅自己可见;原样发布就 `finalize_upload(version_id, manifest)`。
- 前提是发布者允许复制、且这条链接不用口令就能打开:不允许 → 403 `copy_not_allowed`;要口令 / 只对成员可见 → 403 `link_not_open`;撤销 / 过期 / 已删 → 410 `link_gone`。把那句理由转告用户,**别绕**(别去抓页面正文再自己发一份)。
- 自己发的成果想让别人能复制:建成果时 `create_proposal` 传 `allow_copy: true`。
### 对活页本身有意见(给活页团队,不是给某份成果)
- `send_feedback_to_livepage`(写):用户说「这个不好用」「能不能加个…」时,**先把他的意思写成一段草稿给他看,他同意后**才调,参数 `text`、`user_confirmed: true`(必填,真同意了才传)、`category`(`bug` / `idea` / `other`)、`about`(相关成果的 `proposal_id` 或 `version_id`,可选)。显示问题说不清时:`version_id` 传出问题的那一版(运营会直接打开那一版);有终端时 `attachment: { mime, size }` 可附 1 张截图(png / jpeg / webp / gif,≤5MB),再把图片 PUT 到返回的 `attachment_upload.put_url`。用的哪个 Agent、哪一页、这把连接刚才哪一步出的错,平台自动带上;**别**把页面正文、读者信息、令牌写进 `text`。回 `id` 与 `status`。
- **什么时候该问、什么时候别问**:只在三种时刻主动问一句「要不要我把这个转给活页团队?」—— 用户**明确表达**了对活页的不满或需求;工具**刚报错或拒收**(校验失败、审核被拒、超出上限、被限频);结果里带了 `feedback_hint` 或兼容提醒 `compat_notes`。其余时候别问(发布成功、查数据、改稿、接入验证都不问),同一工作区 24 小时内最多问一次,用户说不用就别再提。**不索要评价**:不问满意度、不请用户打分、不在每次发布后问「好不好用」。看到 `feedback_hint` 才提的,调用时另传 `source: "hint"`。
- `list_my_feedback`(读):这个工作区提给活页团队的反馈、状态(new / seen / planned / shipped / wontfix)与我们的回复。用户问「上次提的建议怎样了」时调;有回复就转告。
- 用户卡住了、要的是**真人**而不是提建议 → 别调上面两把,把活页客服链接给他(连接器的 server instructions 里那条;没拿到就给 https://work.weixin.qq.com/kfid/kfc9e1c4b8c05ff167b):手机 / 微信里点开直接进企业微信客服会话,电脑上用微信扫任意后台页页脚「找真人客服」的二维码。错误提示里的「联系我们」指的就是它。
## 纪律
1. 对外的时刻(放开可见性、把链接发出去、打开收录)必须**用户明确确认**后才做。
2. 一份方案只有那一条链接;要给一群人看就 `set_visibility passcode`,要公开传播必须显式 `set_visibility public`。别为了「分人」去拼第二条链接。
3. 校验失败按返回的 `fix` 改,重新上传,不绕过。
4. 阅读情况的结论由你产出、平台只给事实;证据档位不够就说不够,认不出人就别说人名。
## 异常与恢复
- **超时 / 连接失败**:公网 HTTPS,重试一次;仍失败告诉用户「活页暂时连不上」,不编结果。
- **授权失效(401)**:提示重新扫码授权。
- **参数错误(如 visibility 不在枚举、files 为空)**:按上面的取值改正后重试。
- **配额超出(quota_exceeded)**:把返回里的 fix 原样告诉用户(删旧版本 / 联系运营)。
- **审核命中(review)**:客户暂看旧版;告诉用户在管理台复核,不要反复重传同一内容。
## 下载材料(Web / MCP / CLI 同一份配置)
- 下载的是本版本明确选择的已上传文件。正文原文件和附加材料分别选择;首版默认无下载,Markdown 源文件也不自动加入。省略 manifest.downloads 会继承当前生效版的明确选择;显式 [] 清空。旧字符串清单仍兼容。
- manifest.downloads 推荐用对象:
```json
{"schema":1,"enabled":true,"source":null,"attachments":[{"path":"handout.pdf","label":"项目介绍","description":"方案与实施安排","showFilename":false,"downloadName":"项目介绍.pdf"}]}
```
- source 为 null 表示不提供正文原文件;需要时填同样的文件对象,path 必须是本次正文入口(Markdown 指源 .md)。附件数组顺序就是展示顺序;每项 label 必填。格式和大小取实际文件,downloadName 必须保留原扩展名。showFilename 默认 false;只有明确开启才展示原文件名。旧版保存新配置前保持原有名称。
- MCP `get_downloads` 读取清单、可选文件和 revision;`set_downloads` 带 version_id、revision 和完整 config 保存。只读成员不能修改。遇到冲突先重新读取并核对,不盲目覆盖。enabled=false 同时关闭入口与下载地址,保留选项。
- CLI v3:push 可加 `--downloads downloads.json`;配置文件或 `--manifest` 文件本身不上传。读取用 `node space.mjs downloads --version <id>`;修改用 `node space.mjs downloads --version <id> --config downloads.json --revision <读到的修订号>`。所有命令沿用 SPACE_TOKEN。
- CLI push 在提交前列出材料新增、移除、同路径文件替换和缺失;缺失会阻止提交。手工 MCP 上传在 create_upload_session 后用 `preview_downloads`,把返回的 basis 交给 finalize_upload 的 download_basis。路径不会模糊重配;目录改名应明确更新清单。需要人工看完再生效时用 --hold。
- Web 在成果详情的「下载材料」里编辑,也可按版本查看与生效版的差异。当前版保存即应用;其他版本的设置随各自版本使用。单份直接下载,多份打开有名称、说明、格式和大小的清单。新配置的下载入口独立于「更多」。
- 不做服务器 HTML 转 PDF,也不打 ZIP:HTML 原文件只含入口文件;完整讲义应先本机导出 PDF 再随包上传、加入清单。渲染所需资源仍可被浏览器读取,下载设置不是防复制措施。
## 数据表(挂在方案上,不随版本;MCP / CLI / REST 同一份)
- 一份方案可以挂若干张 CSV / JSON 数据表。表挂在**方案**上、不挂版本:改数据不用重发页面,push 新版本(含 `--hold`)也不会动表。每张表有修订号 revision。
- MCP:`get_data`(不传 table 列出全部表与三条上限;传 table 返回 columns / rows / revision,format=csv 另附 CSV 文本)· `set_data`(新建 revision 传 0;修改 / 删除必须原样带回 `get_data` 给的 revision,不一致会被拒并要求先读回,不能盲目覆盖;delete=true 删表)。`list_proposals` 会标出每份方案有几张表。`set_data` 的 `append_open` 与 `list_data_rows`(读者写回的行)见下面「读者写回」。 报名 / 订货 / 预约 / 留资这类填表场景用 `set_form`(一等公民表单块,见下面「读者写回」末尾)。
- CLI:`node space.mjs data pull --proposal <id> --out <目录>`(每张表一个 <表名>.csv,`--json` 则 .json)· `node space.mjs data push <file.csv|file.json> --proposal <id> --table <name> [--revision <n>]`(新建缺省 0)· `node space.mjs data delete --proposal <id> --table <name> --revision <n>`。
- 表名小写字母开头、只含字母数字下划线;每格只收文字 / 数字 / 真假 / 空(嵌套先摊平)。上限:单表 512 KB、每份方案 20 张、工作区合计 64 MB,回执逐条印出。
- 读权限跟方案可见性走、不另造授权:private 只有成员与批过的设备、口令过门后可读、public 任何人可读;重置默认链接后旧链接读不到;无权限是 403 不是空表。
- **页面取数用最普通的 `fetch`**(#8654 起):`fetch('./_data/表名.json')` 拿到行对象数组(底表 + 过审的读者写回;发布者自己看还会多出待审的行),修订号在响应头 `X-Space-Revision`;读权限就是方案可见性,无权限是 403 不是空数组。线上没有这张表时回落包里同名的 `_data/表名.json` ⇒ 本地放一份示例数据、`node space.mjs serve` 就能跑。只改表不重传页面,读者刷新即见新数据。旧的 SDK 写法 `space.data.get('表名')`(回 `{columns, rows, revision}`)继续可用,是可选的兼容层。
- **删除成果(#7959 起)**:`delete_proposal`(要 `confirm` 原样传标题)—— 链接**立刻失效**、从列表与统计里消失,30 天内可 `restore_proposal` 恢复,之后平台彻底清除(内容、版本、页图、阅读记录、读者写回的行都不再存在,不可逆)。要立刻彻底清除去管理台。有待处理举报的成果不能删。
- **存储满了(#8713 起)**:报 `quota_exceeded`「存储空间已满」时,先跟用户确认,再用 `revoke_versions`(`confirm` 原样传标题)撤回那份成果的旧版本 —— 当前版本与链接不受影响,立刻释放存储。同一份文件在各版本之间只算一次,所以反复更新同一页本身不会占满。
- **读者写回(报名 / 打卡 / 投票 / 意见收集,#7624 起)**:页面往同一张表写一行 —— 普通表单 `<form action="./_data/表名" method="post">`,或 `fetch('./_data/表名', {method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({列: 值})})`(旧 SDK `space.data.append('表名', {列: 值})` 同一件事)—— **默认关、按表开**:`set_data` 传 `append_open=true`(单独传只翻开关、不动底表,仍要带 revision)。写回限频(每张表每小时 600 行、每台设备 30 行)、每行不超过 2000 字 / 单格 500 字、每表最多 5000 行;文字先过审:过审的行其他读者刷新即见,审核命中的行只有发布者看得到,审核不可用时写回被拒(页面收到「稍后再试」)而不是先收下。关着时写口回 `403`、`code` 为 `append_closed`(SDK 则 reject 同一个 `err.code`),页面要把原因给读者看、别假装「已提交」。写回的行**不在** `get_data` 的 rows 里、也不会被 `set_data` 覆盖,用 `list_data_rows` 读回(可按表 / 状态过滤,带设备、时刻、写回时的页面版本与数据修订;只有设备与时刻,不认人、别据此推断意愿);要并进底表就读回后 `set_data` 整表替换。**审核拦下来的行要你决定**:`set_data_row_status`(`action=approve` 放行给读者看 · `hold` 收回只有你看 · `delete` 真删,不可撤销)——approve / hold 双向,看走眼能改回来;delete 之后那一行不会再出现在页面、导出或统计里。放行会顺手把这一行的审核命中标成误伤(按「发布者放行」单独记)。每次处置方案的数据修订 +1。写回只对读得到这份内容的设备开放(private / 口令与页面同口径),重置默认链接后旧链接的写回一并失效;每次写回都进访问时间线(`get_session_timeline` 里是「写回」)。预览台、讲解人与发布者自己的会话不提交。
- **一等公民表单 / 订单块(报名 / 订货 / 预约 / 留资,#8273 起)**:页面上一行表单代码都不想写时用它(自己写普通 `<form>` 同样可以)—— `set_form` 只定义字段(最多 20 个,六种类型:text / textarea / select / multiselect / number / phone),平台在查看页里把它渲染成手机上能填、带校验的表单,提交的行落到同一张数据表、用 `list_data_rows` 读回(每行带 _form_rev;审核、限频、held 与上面那条一样)。可选 amount 只显示金额(单价 × 数量由平台算、写进每行的 _amount_cents),不收钱。幂等:再调一次就是改字段,已收的行保留;写回默认打开,传 `append_open=false` 关掉。页面不用重发。
- **收款指引(#8276 起,钱不经平台)**:表单带 `amount` 且这个工作区设过**经营收款码**(商户收款码,不是个人码 —— 2022-03-01 条码支付新规;用 `set_payment_qr` 传 base64 的 PNG / JPEG,不必让用户去管理台,撤掉用 `remove_payment_qr`;**换码是唯一「改错了钱会悄悄流到别处」的设置**,每次写都留痕并给工作区负责人推一条微信,传之前先跟用户确认那是他本人的商户码)时,读者提交成功后页面在原地展开付款那一段:应付金额、发布者自己的收款码,和一枚「我已付款」。读者点的那一下只是**自称**,不是支付结果;发布者在自己的收款账单里核对到账后用 `confirm_payment` 确认,读者再打开那一页就看到「商户已确认到账」(只有他自己那一行看得到)。两个标记都**不改**这一行的审核状态;`list_data_rows` 每行会印金额与付款状态。没传收款码 ⇒ 只显示金额,付款那一段不出现。
## 成果录制与动线
- HTML 成果的后续访客访问默认录制,`set_replay` 可单独关闭;主动停录跨发版、移夹与链接重置保留。
- `get_replay_settings` 读取空间总开关、容量与保留期;`set_replay_settings` 仅负责人可改,关闭会覆盖所有成果和历史链接,重新开启保留单份停录设置。
- 管理台入口 `/app/recording`;REST 为 GET / POST `/api/workspace/replay`,POST 的 `enabled` 必须是布尔值。
- 回放独立容量每空间 1 GB,每次最多 8 MB,画面保留 30 天。达到上限停止采集,后台暂停,返回后重新快照;不占成果文件上传额度。
- 输入内容遮罩。敏感正文用 `data-space-private` 或 `rr-block` 标记;Canvas / WebGL 暂不录制,不承诺所有互动能完整回放。
- `list_sessions` / `get_session_timeline` 返回 `replayStopReason` 和 `replayHadPause`,向用户解释容量、上传中断与后台暂停;基础动线及 PDF/PPTX 逐页回放不依赖画面录制。
Attribution
Related skills
View all in data →Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.