6.7 KiB
更新在线文字文档
唯一推荐入口
普通追加、覆盖和 block 编辑统一使用 +update:
--command 只接受下列枚举值,不接受 JSON、自然语言或拼接子命令;动作参数必须分别传给 --content/--old/--new/--block-id/--before-block-id/--after-block-id。
dws doc +update --node <DOC_ID> --command append --content "补充说明" --format json
dws doc +update --node <DOC_ID> --command append --content @append.md --format json
dws doc +update --node <DOC_ID> --command overwrite --content @full.md --format json
dws doc +update --node <DOC_ID> --command overwrite --doc-format jsonml --content @full.json --expected-revision <REVISION> --format json
dws doc +update --node <DOC_ID> --command block_insert_before --before-block-id <BLOCK_ID> --content "发布说明" --heading-level 1 --format json
dws doc +update --node <DOC_ID> --command block_replace --block-id <BLOCK_ID> --content "新内容" --format json
重要覆盖或明确要求恢复点时使用:
dws doc +checkpoint-update --node <DOC_ID> --mode overwrite --content @full.md --format json
+checkpoint-update 负责保存版本、写入和回读,不要手工编排 version save → update → read。
动作与输入
--command |
用途 | 必要参数 |
|---|---|---|
append |
末尾追加 | --content |
overwrite |
整篇覆盖 | --content;JSONML 可加 --expected-revision 做服务端原子条件写 |
block_insert_before |
在指定 block 前插入段落或标题 | --before-block-id --content;标题加 --heading-level 1..6 |
block_insert_after |
在指定 block 后插入段落或标题 | --after-block-id --content;标题加 --heading-level 1..6 |
block_replace |
替换指定 block | --block-id --content |
block_delete |
删除指定 block | --block-id |
str_replace |
唯一普通文本替换 | --old --new |
block_copy_insert_after |
复制 block 后插入 | --block-id --after-block-id |
统一输入协议:已有或临时文件先暂存到当前工作目录后传 @相对文件;单次生成文本可用 --content - 从 stdin 读取。禁止绝对路径、..,也不要猜测 --content-file、--content-format 或 replace_all。
block ID 必须来自 +fetch --detail with-ids 或真实 block 列表,禁止编造。
--expected-revision 只允许 --command overwrite --doc-format jsonml。Markdown、append 和 block 接口没有服务端原子 revision 契约,禁止用写前读取模拟乐观锁。
新增结构化标题
“新增/插入标题”与“修改现有块文字”不是同一动作。+update block_replace --content "# 标题" 会替换原块并可能落成普通 paragraph,不能用它冒充 heading。
需要在已有首块前新增标题时,先用 +fetch --detail with-ids 取得真实首块 ID,再走结构化插入:
dws doc block insert --node <DOC_ID> --heading "发布说明 v1.0" --level 1 --ref-block <FIRST_BLOCK_ID> --where before --format json
插入回执有新 block ID 时定点 block list --block-id;只有插入 index 时执行一次完整 block list --content-format jsonml 并按 index 验证 blockType=heading、回读投影 heading.level="heading-1" 和文字。block list 没有 --limit,禁止通过 Help 猜参数;CLI 写入仍用 --level 1。只核对可见文字不算结构验收。已有标题改级别或改文字时使用结构化 doc block update --heading/--level;更多块边界见 doc-block.md。
最小改写决策
| 已知条件 | 推荐路径 | 成本与成功率理由 |
|---|---|---|
| 用户明确要求在末尾追加 | 直接 append |
不为找末尾先拉全文;需要语气衔接时只读末节 |
| 已知唯一旧文本与新文本 | 直接 str_replace --old --new |
省掉 block 解析;旧文本不唯一时 Runtime 必须失败,不放宽匹配 |
| 指定章节但没有 block ID | +fetch outline → +fetch section --detail with-ids → block 动作 |
两个小读取换取稳定锚点,避免全文 token 和误改相邻章节 |
| 已知真实 block ID | 直接 block_replace/delete/insert_before/insert_after |
最小副作用;不改无关 block |
| 多个待删除 block ID 已全部取得 | 在同一个 fail-fast 工具轮中按顺序执行全部 block_delete |
中间不重读 Reference、不重复 fetch;任一失败立即停止并保留未执行清单 |
| 多处富结构保真修改 | +fetch --detail full 后定点 JSONML 更新 |
保留图片、附件、引用、表格和样式;不要从 Markdown 有损重建 |
| 整篇重要覆盖 | +checkpoint-update --mode overwrite |
自动保存恢复点、执行并回读;普通 overwrite 只用于明确不需恢复点的场景 |
同一篇文档的正文由一个主上下文串行维护:Plan(确定最小变更)→ Execute(一次写)→ Observe(先消费回执)→ Iterate(只修未达标部分)。不要按章节并行写同一文档,也不要每次迭代都重新读取全文或 Schema。
Block ID 生命周期与保真
block_replace成功后 Runtime 使用同一blockId回读验证,该 ID 可继续作为锚点;验证失败时先局部+fetch核对现状。block_delete成功后旧 ID 失效,不得继续复用。block_insert_before/block_insert_after/block_copy_insert_after后,原锚点通常仍可识别,但新 block 的 ID 必须来自真实返回或局部回读,禁止按顺序猜测。str_replace的简单行内替换通常不要求重新取 ID;若后续依赖块结构,仍以局部回读为准。- 从 Markdown 读取后覆盖整篇可能丢失图片、附件、@人/@文档、评论锚点、表格样式和嵌套块。只改局部时使用 block 手术;确需整篇保真改写时使用
fullJSONML,并以--expected-revision防止覆盖并发修改。
确认与验证
+update与+checkpoint-update当前都要求用户确认。目标、动作、内容范围或参数变化后必须重新确认;只有发现本地文档与 live leaf 漂移时才查一次精确 Schema,禁止每次写入都重复发现。+update已负责回读验证。除非结果为unknown或任务需要额外结构验收,不要再做一次全篇读取。doc_write_verification_failed表示写入已经发生,必须先读取现状;禁止直接重复写入。partial_success只恢复未完成步骤,不能重放成功步骤。
高级通道
只有 shortcut 未公开底层参数或必须保留原始响应时,才读取精确 leaf Schema 后使用 dws doc update / doc block。富结构保真按需读取 doc-update-workflow.md,但执行入口仍优先使用 +update/+checkpoint-update。