@iqiyi-intl-nadoupro/nadoupro-cli 1.0.0-test.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +25 -0
  2. package/package.json +42 -0
  3. package/scripts/bootstrap.js +393 -0
  4. package/scripts/install.js +99 -0
  5. package/scripts/run.js +65 -0
  6. package/scripts/skill-sync.js +18 -0
  7. package/skills/nadou/SKILL.md +68 -0
  8. package/skills/nadou/commands/audio.md +125 -0
  9. package/skills/nadou/commands/auth.md +91 -0
  10. package/skills/nadou/commands/canvas-attachment.md +71 -0
  11. package/skills/nadou/commands/canvas-edge.md +65 -0
  12. package/skills/nadou/commands/canvas-graph.md +191 -0
  13. package/skills/nadou/commands/canvas-management.md +77 -0
  14. package/skills/nadou/commands/canvas-media.md +377 -0
  15. package/skills/nadou/commands/canvas-node.md +228 -0
  16. package/skills/nadou/commands/canvas.md +123 -0
  17. package/skills/nadou/commands/evidence.md +30 -0
  18. package/skills/nadou/commands/image-tools.md +88 -0
  19. package/skills/nadou/commands/image.md +273 -0
  20. package/skills/nadou/commands/material.md +59 -0
  21. package/skills/nadou/commands/media.md +156 -0
  22. package/skills/nadou/commands/model.md +103 -0
  23. package/skills/nadou/commands/points.md +43 -0
  24. package/skills/nadou/commands/schedule.md +112 -0
  25. package/skills/nadou/commands/space.md +253 -0
  26. package/skills/nadou/commands/system.md +50 -0
  27. package/skills/nadou/commands/task-request.md +188 -0
  28. package/skills/nadou/commands/task.md +229 -0
  29. package/skills/nadou/commands/text.md +81 -0
  30. package/skills/nadou/commands/video-advanced.md +96 -0
  31. package/skills/nadou/commands/video.md +247 -0
  32. package/skills/nadou/guides/artifact-presentation.md +146 -0
  33. package/skills/nadou/guides/canvas-dependency-graph.md +101 -0
  34. package/skills/nadou/guides/canvas-first-complex-workflow.md +83 -0
  35. package/skills/nadou/guides/execution-interaction.md +54 -0
  36. package/skills/nadou/guides/failure-cost-presentation.md +42 -0
  37. package/skills/nadou/guides/intent-templates.md +53 -0
  38. package/skills/nadou/guides/model-rules.md +7 -0
  39. package/skills/nadou/guides/utf8-input-safety.md +13 -0
  40. package/skills/nadou/node-types/audio.md +66 -0
  41. package/skills/nadou/node-types/clip.md +43 -0
  42. package/skills/nadou/node-types/director3d.md +41 -0
  43. package/skills/nadou/node-types/group.md +59 -0
  44. package/skills/nadou/node-types/image.md +137 -0
  45. package/skills/nadou/node-types/index.md +77 -0
  46. package/skills/nadou/node-types/json-contract.md +275 -0
  47. package/skills/nadou/node-types/model3d.md +35 -0
  48. package/skills/nadou/node-types/storyboard.md +43 -0
  49. package/skills/nadou/node-types/text.md +93 -0
  50. package/skills/nadou/node-types/video.md +119 -0
  51. package/skills/nadou/policies/core-safety.md +35 -0
  52. package/skills/nadou/policies/cost-and-write.md +37 -0
  53. package/skills/nadou/policies/result-and-recovery.md +41 -0
  54. package/skills/nadou/recipes/atomic-image.md +77 -0
  55. package/skills/nadou/recipes/canvas-image.md +92 -0
  56. package/skills/nadou/recipes/one-click-film.md +234 -0
  57. package/skills/nadou/recipes/quality-review.md +95 -0
  58. package/skills/nadou/recipes/typical-flows-host-adaptation.md +113 -0
  59. package/skills/nadou/workflows/atomic.md +61 -0
  60. package/skills/nadou/workflows/canvas.md +59 -0
  61. package/skills/nadou/workflows/local.md +41 -0
  62. package/skills/nadou/workflows/task-recovery.md +45 -0
@@ -0,0 +1,68 @@
1
+ ---
2
+ name: nadou
3
+ description: "通过纳逗Pro完成文本、图片、视频、音频、空间、任务、画布与本地媒体工作。仅当用户显式提到 nadou、nadoupro、Nadou Pro、纳逗或纳逗Pro,或当前宿主/产品上下文已明确指定纳逗Pro时使用。普通未指定平台的通用生成、编辑或媒体请求不要自动触发;仅讨论、分析或引用通用创作概念,或已指定其他平台时也不触发。"
4
+ metadata:
5
+ version: "1.0.0-test.2"
6
+ ---
7
+
8
+ # 纳逗Pro
9
+
10
+ ## 标准入口
11
+
12
+ 1. 每个用户回合首次执行产品操作前先运行 `nadou version --json` 并读取 `meta.auth_mode`。仅当当前模式使用本地用户 OAuth 时,才运行 `nadou auth status --no-interactive --json`;只有状态明确要求登录时,说明会打开浏览器并在用户同意后执行登录。其他认证模式按对应政策执行,不用 OAuth 状态推断其可用性。
13
+ 2. 按用户目标选择一个主模式,读取对应工作流和适用政策;再用 `capability describe`、命令 `--help` 与 `model schema` 获取当前事实,不因文档或示例中出现某项能力就假定当前账号可用。
14
+ 3. 仅在实际发生费用、目标选择或写入时展示摘要并取得授权;确认后写请求只发送一次,保存 `meta.request_id`、任务、画布、节点和变更标识用于观察与恢复。
15
+
16
+ ## 全局不变量
17
+
18
+ 1. **只走 CLI**:所有纳逗业务操作只调用已安装的 `nadou`。不得直连后端、扩展未登记接口,或读取、索要、保存、展示 `Cookie`、`token`、`Authorization` 等凭据。
19
+ 2. **先定模式**:在写入前把当前步骤归入独立原子、画布、本地处理或任务恢复。模式可以按用户目标串联,但不得静默互换或冒充彼此结果。
20
+ 3. **事实现查**:命令、参数和副作用以当前 CLI 的 `capability`、`--help` 与结构化响应为准;模型、空间、目录、画布、节点、任务和素材 ID 必须实时查询,不按名称、旧会话或示例猜测,也不得把已知业务名词拼接成未经发现的新命令(例如不存在 `nadou canvas points`)。
21
+ 4. **自动化输出契约**:除 `skill`/`capability` 等本地框架命令外,每个远程业务命令都显式使用 `--no-interactive --json`(流式观察使用 `--jsonl`)。`--json` 保证结构化输出,`--no-interactive` 保证不会等待终端输入;两者都不能替代费用、目标或破坏性操作授权。
22
+ 5. **生成命令输入门禁**:禁止猜测 `nadou video models`、`nadou image models`、`nadou text models` 或 `nadou audio models`;模型发现统一使用 `nadou model list` / `nadou model schema`。非交互或 `--json/--jsonl` 机器模式的原子生成必须先使用显式 `--prompt`、`--prompt-file` 或 `--stdin`,并在正式提交时显式带 `--submit`;位置参数只有在交互式调用、`--dry-run` 预览或已明确带 `--submit` 时才接受。
23
+ 6. **适用门禁**:只有命中费用、目标选择、上传、远端或本地写入、定时或破坏性操作时,才在执行前披露对象、目标、副作用与费用并取得授权。请求、环境、计费空间、目标或关键参数变化后,旧授权失效。
24
+ 7. **一次写入**:每个已确认动作只提交一次。超时、断网、冲突、部分成功或结果未知时保留原标识,先只读恢复或对账,不自动重建、换 ID、改投或重提。
25
+ 8. **只报证据**:只呈现 CLI 已核实的任务、产物、空间、画布和本地文件事实;分别报告生成、在线结果、空间交付、画布回填和本地交付,不拼接链接、路径或成功状态。
26
+
27
+ ## 选择执行模式
28
+
29
+ 每个步骤只选择一个主模式并读取对应工作流;混合目标拆成有顺序的步骤。
30
+
31
+ | 模式 | 进入条件 | 必读工作流 | 核心边界 |
32
+ | --- | --- | --- | --- |
33
+ | 独立原子 `atomic` | 用户未指定画布,要求独立文本、图片、视频或音频任务 | [独立原子创作](workflows/atomic.md) | 不隐式创建画布节点;不自动下载到本地 |
34
+ | 画布 `canvas` | 用户要求管理画布本身,或明确给出/选择画布、节点、连线、编辑、剪辑或导出 | [画布工作流](workflows/canvas.md) | 区分画布管理与画布内容管理;同批多节点用一次有序 `operations`;不改走独立 `nadou image/video/audio` |
35
+ | 本地 `local` | 用户明确要求下载、字幕、拼接、混音、规范化、检查或证据文件 | [本地处理与交付](workflows/local.md) | 不把本地产物说成平台回填、空间交付或画布产物 |
36
+ | 任务恢复 `task-recovery` | 用户提供已有任务 ID,或要继续等待、查询、下载、交付或处理未知结果 | [任务恢复](workflows/task-recovery.md) | 不以新任务替代原任务;重新生成是新的授权步骤 |
37
+
38
+ ## 认证上下文
39
+
40
+ - 默认使用当前 profile 的用户 OAuth 身份;登录、账号、空间权限与可用能力均按 [认证参考](commands/auth.md) 和 CLI 实时结果确认,不从文档声明推断账号授权。
41
+
42
+ ## 按副作用读取政策
43
+
44
+ - 所有模式先读取 [核心安全边界](policies/core-safety.md)。
45
+ - 涉及扣费、远端/本地写入、上传、删除、覆盖、移动或定时提交时,再读取 [费用与写入](policies/cost-and-write.md)。
46
+ - 涉及异步任务、回填、失败、冲突、超时、部分成功、结果未知或最终交付时,再读取 [结果与恢复](policies/result-and-recovery.md)。
47
+
48
+ ## 动态发现与加载预算
49
+
50
+ - 标准执行只加载本文件、一个模式工作流和适用政策;标准独立生图最多 5 个文件。
51
+ - 命令与参数先用 `capability describe`、对应命令 `--help` 和 `model schema` 获取。仍有一个具体语义不清时,再按工作流中的直接链接读取一页参考,不批量预读。
52
+ - 完整命令事实位于 `commands/`,画布节点契约位于 `node-types/`;这些是按需参考,不是入口必读内容。
53
+ - 可复制场景位于 `recipes/`,只在用户要求操作手册或任务确需完整示例时读取,不把配方当成 CLI 能力:[独立图片](recipes/atomic-image.md)、[画布图片](recipes/canvas-image.md)、[一键成片](recipes/one-click-film.md)、[质量复核](recipes/quality-review.md)、[宿主适配示例](recipes/typical-flows-host-adaptation.md)。
54
+
55
+ ## 诊断与消歧入口(默认不读)
56
+
57
+ 失败先保留 `meta.request_id` 及已有任务、画布、节点和变更标识;环境问题运行 `nadou doctor --json`,写结果未知按 [结果与恢复](policies/result-and-recovery.md) 只读对账。下列链接只用于仍未解决的单点消歧,每次最多选一页;参数仍以当前 CLI `--help` 为准。
58
+
59
+ | 主题 | 直接参考 |
60
+ | --- | --- |
61
+ | 版本、环境诊断、request ID 与 Skill | [系统](commands/system.md) |
62
+ | 登录、空间与素材 | [登录](commands/auth.md)、[空间](commands/space.md)、[素材](commands/material.md) |
63
+ | 模型与独立创作 | [模型](commands/model.md)、[文本](commands/text.md)、[图片](commands/image.md)、[图像工具](commands/image-tools.md)、[视频](commands/video.md)、[音频](commands/audio.md)、[高级视频](commands/video-advanced.md) |
64
+ | 独立媒体请求与费用 | [任务请求](commands/task-request.md)、[积分](commands/points.md) |
65
+ | 任务、定时与恢复 | [任务](commands/task.md)、[定时](commands/schedule.md)、[失败与费用事实](guides/failure-cost-presentation.md) |
66
+ | 画布与成片 | [画布](commands/canvas.md)、[画布媒体](commands/canvas-media.md)、[画布优先工作流](guides/canvas-first-complex-workflow.md) |
67
+ | 本地媒体 | [本地媒体](commands/media.md) |
68
+ | 意图、交互与呈现 | [意图模板](guides/intent-templates.md)、[执行交互](guides/execution-interaction.md)、[产物呈现](guides/artifact-presentation.md) |
@@ -0,0 +1,125 @@
1
+ # 音频
2
+
3
+ `nadou audio` 是独立原子音频任务入口。`text2audio`(文生音频)和 `audio2audio`
4
+ (音频参考生成)为已验证执行场景;`text2speech`(配音)和 `voice_conversion`(音色转换)
5
+ 为 contract-ready 的 target 场景,可动态发现和本地预览,但尚不开放真实估价或提交。它不创建画布节点,也不在
6
+ 原子命令中隐式写入空间或本地文件。入口 Agent 默认编排在线结果和空间交付;本地副本只在用户明确要求时编排。
7
+
8
+ 用户明确要求在既有 Canvas 音频节点中生成时,不使用独立 `nadou audio`。读取实时 Graph 和音频节点配置,
9
+ 走 `canvas node estimate`、`canvas node generate`、`canvas node wait`;该路由在 Canvas 内由回调写回,
10
+ 不创建个人空间副本。独立音频与 Canvas 音频必须保持为两条不同路由。
11
+
12
+ ## 动态发现与场景选择
13
+
14
+ 执行前按场景读取当前账号的 `TEXT_TO_AUDIO_MODEL_CONFIG`、`AUDIO_TO_AUDIO_MODEL_CONFIG`、
15
+ `TEXT2SPEECH_MODEL_CONFIG` 或 `VOICE_CONVERSION_MODEL_CONFIG`,通过
16
+ `model list --scenario text2audio|audio2audio|text2speech|voice_conversion` 和 `model schema` 获取模型、参数枚举、时长、
17
+ 格式、数量及引用上限。禁止在 Skill、提示词模板或命令脚本中写死 `suno-v50` 或任何默认值。
18
+ 目录缺少所需字段时必须失败关闭并报告后端目录契约缺口。
19
+
20
+ 当运行时 schema 提供 `bgm` 时,可向 `nadou audio` 传 `--bgm 开|关`(也接受目录声明的
21
+ 布尔值形式)。CLI 将其解析为布尔 `params.bgm`。Mureka 的公开提交模型仍保持目录中的
22
+ `mureka-v8-p-s` 或 `mureka-v9-p-s`;`bgm=true` 不把请求模型名改写成内部 `g-b` 名称。
23
+ 该规则同时适用于 `text2audio` 和 `audio2audio`,目录未声明 `bgm` 时本地失败关闭。
24
+
25
+ ## 配音与音色转换(target)
26
+
27
+ 配音要求非空台词和显式正整数 `--sound-id`,且不接受音频引用:
28
+
29
+ ```sh
30
+ nadou audio --scenario text2speech --model <catalog-model-id> \
31
+ --sound-id 123 --prompt "你好,欢迎回来。" --dry-run --json
32
+ ```
33
+
34
+ 音色转换允许空提示词,但要求恰好一个可信公开 HTTPS 音频 URL;只有当前 Schema 声明对应字段时,
35
+ 才可使用 `--cross-gender 开|关|true|false` 和 `--pitch-shift 更低沉|标准|更尖细|-2|0|2`:
36
+
37
+ ```sh
38
+ nadou audio --scenario voice_conversion --model <catalog-model-id> \
39
+ --sound-id 123 --reference https://example.com/source.wav \
40
+ --cross-gender 开 --pitch-shift=-2 --dry-run --json
41
+ ```
42
+
43
+ 预览返回规范化业务请求及 `request_sha256`;任一输入改变后旧摘要失效。当前两条 concrete task semantic
44
+ 仍标记为 `target`,因此去掉 `--dry-run` 或尝试用户可见 Canvas 估价/生成都会在业务客户端调用前返回
45
+ `TASK_CONTRACT_UNVERIFIED`。不得绕过该门禁,也不得通过名称、头像、历史缓存猜测 `soundId`。
46
+ CLI 不搜索或创建设计音色,不使用 `groupId` 代替服务端 workflow/project 权限判断。
47
+
48
+ ## 文生音频
49
+
50
+ ```sh
51
+ nadou audio "夏日午后、柠檬水气泡和轻快 indie pop" \
52
+ --scenario text2audio --profile <profile> --dry-run --json
53
+ ```
54
+
55
+ 非交互或 `--json/--jsonl` 机器模式的正式提交必须带 `--submit`;优先使用显式 `--prompt`、
56
+ `--prompt-file` 或 `--stdin`,位置提示词仅在已明确带 `--submit` 时接受;
57
+ 位置参数仅用于交互式调用或 `--dry-run` 预览。不要把 `nadou audio models` 当作模型发现命令,
58
+ 模型目录必须使用 `nadou model list`。
59
+
60
+ ## 音频参考生成
61
+
62
+ ```sh
63
+ nadou audio "把参考旋律改编成轻快版本" \
64
+ --scenario audio2audio \
65
+ --reference https://example.com/reference.mp3 \
66
+ --profile <profile> --dry-run --json
67
+ ```
68
+
69
+ `audio2audio` 的引用必须是无凭证、无 fragment 的公开 HTTPS 音频 URL,并满足当前模型
70
+ 参数结构声明的数量和媒体类型。不能把本地路径、HTTP 地址、图片/视频 URL 或任务状态塞入
71
+ `--reference`。本地文件若确实需要进入任务,必须先通过已批准的显式 `material upload` 获得
72
+ 服务端 URL;该上传不是空间交付,也不自动关联画布。
73
+
74
+ ## 费用、提交和恢复
75
+
76
+ 先运行 `--dry-run --json`,保存 `data.request`。入口 Agent 读取 [task-request.md](task-request.md),
77
+ 查询当前计费空间余额,将同一请求交给 `task estimate`,展示模型、场景、关键参数、
78
+ 数量、预计消耗和计划交付目标,得到用户确认后才调用 `task submit`。估价不锁价;请求发生变化
79
+ 必须重新预演/估价。`--no-interactive` 不能把未授权任务静默提交,除非调用方已提供明确预算授权。
80
+
81
+ 提交最多一次。用户完成费用确认后,入口 Agent 默认在同一轮中立即提交,并使用返回的任务 ID
82
+ 继续等待、读取产物和执行计划交付;不得再次询问用户是否需要等待。只有用户明确要求“仅提交”时
83
+ 才在任务 ID 返回后停止。等待/产物读取/网络结果未知时保留任务 ID、请求 ID 和恢复动作,
84
+ 禁止重新提交或自动重试写请求。
85
+
86
+ 音频属于长耗时媒体任务。未指定超时时,`nadou audio --wait` 和识别为音频的
87
+ `nadou task wait` 使用与视频一致的 10 分钟本地观察窗口;显式超时优先,窗口超时不代表
88
+ 远端任务被取消。后端可能在 `jobList` 中返回多个音频作业,或在单个作业的 `productUrl`
89
+ 中返回列表;CLI 会按服务端顺序展开为 `outputs[]`,并为每项返回稳定的 `output_index`。仅
90
+ `TEXT2AUDIO`/`AUDIO2AUDIO` 且实际作业数不超过权威 `generateCount` 时,才允许 `jobCount`
91
+ 小于实际作业数;缺少数量上限、超过上限、重复或非法作业均停止并保留任务 ID。
92
+
93
+ ## 提交前确定空间目录与在线交付
94
+
95
+ 空间交付和服务端在线结果是音频入口默认交付。本命令不会自动下载或创建本地清单;只有用户明确要求本地文件时,
96
+ 才披露绝对目标目录和不覆盖规则,并在取得可信任务/作业/产物后执行:
97
+
98
+ ```sh
99
+ nadou task download-batch --task-id <task-id> \
100
+ --output-dir <absolute-target>/artifacts \
101
+ --manifest <absolute-target>/download-manifest.json \
102
+ --profile <profile> --json
103
+ ```
104
+
105
+ 未指定个人/团队目录时,入口在费用确认前通过 `space current` 和 `space directory list` 列出目标空间全部目录候选,
106
+ 不得直接选择个人空间根目录;用户必须在同一条摘要确认中选择目录并确认费用。只有已处于 `delivery_status=AWAITING_DESTINATION` 的任务才恢复目录选择与交付。
107
+
108
+ 独立音频的团队目录交付若返回 `PERMISSION_DENIED` 或 `DELIVERY_PERMISSION_DENIED` 且 `fallback_eligible=true`,必须使用 `atomic_media_permission_fallback_prompt`:先展示原团队目录和个人目录候选,等待 `fallback_confirmation_required` 的明确确认;确认前不得写个人空间。拒绝时遵循 `fallback_confirmation_declined`,非交互无预授权时遵循 `non_interactive_fallback_blocked`,确认后仅按 `original_task_reuse_only` 复用原任务/作业/产物,不重新生成音频。
109
+
110
+ 部分失败后只使用 `task download-batch --resume-manifest <manifest>` 恢复,不使用 `--overwrite`,也不重新
111
+ 提交音频任务。`local_delivery_status`、空间 `delivery_status` 与生成状态分别报告。未明确要求本地下载时不创建清单、
112
+ 不报告本地路径;明确画布、仅生成或仅空间交付时同样跳过本地下载。
113
+
114
+ 音频生成完成只代表 `generation_status=COMPLETED`,不代表已写入空间。入口 Agent 在提交确认前已绑定
115
+ 用户选择或明确指定的目录,任务完成后只向该目标执行一次 `space artifact deliver` 并通过目录回读确认;
116
+ 只有成功后才返回实际空间/目录/资源路径和服务端权威 `material_url`(若有)。交付失败/未知时
117
+ 保持生成成功事实并单独返回 `delivery_status`,只恢复原产物交付,不重新提交音频任务。明确指定个人/团队目录、
118
+ 画布或仅下载时跳过默认个人目录解析。
119
+
120
+ ## 未支持能力
121
+
122
+ 音色库搜索/创建、旧 `VC_MODEL_CONFIG`、VC 类旧音色转换、`audio_cut`、`audio_vad_asr`、混音/剪辑、
123
+ 提示词优化和一键成片仍不属于当前 `nadou audio`。用户要求这些能力时停止并说明缺少已批准契约,
124
+ 不以相近平台或本地脚本冒充成功。Canvas `TEXT2SPEECH`/`VOICE_CONVERSION` 当前同样只开放本地构造;
125
+ target 状态下不估价、不提交、不修改 Graph。获得审阅后的真实响应证据并更新 SDD 前,不得称为已支持执行。
@@ -0,0 +1,91 @@
1
+ # 认证
2
+
3
+ 先查看登录状态:
4
+
5
+ ```sh
6
+ nadou auth status --profile <profile> --no-interactive --json
7
+ ```
8
+
9
+ 状态为 `missing`、`expired` 或 `reauth_required` 时执行一次浏览器登录:
10
+
11
+ ```sh
12
+ nadou auth login --profile <profile> --timeout 10m --json
13
+ ```
14
+
15
+ 状态为 `authenticated` 时不要重复登录。`unavailable` 表示当前环境无法访问本机凭据库,
16
+ 不是未登录,不能靠重新登录解决。
17
+
18
+ CLI 会先直接显示授权地址,再尝试打开系统浏览器。自动打开失败时,同一个本地授权会话会继续
19
+ 等待到本次超时;手动打开已经显示的地址即可继续,不要再次执行登录命令。
20
+
21
+ `LOGIN_CANCELLED`、`LOGIN_TIMEOUT`、`LOGIN_BROWSER_FAILED` 或 `LOGIN_DENIED` 的详情会包含
22
+ `login_completed: false`、`login_retry: explicit_only` 和可执行的 `suggested_actions`。
23
+ Agent 应展示该命令并等待用户或宿主显式决定是否重新登录,不得自动执行。
24
+
25
+ `CREDENTIAL_STORE_UNAVAILABLE` 同样表示当前终端或沙箱无法访问操作系统安全凭据存储。
26
+ 重新登录不能自行获得 Keychain、Credential Manager 或 Secret Service 权限;应修复当前环境
27
+ 的凭据库访问,或在受控 Agent/CI 环境使用已批准的 Secret 注入。不得把 token 写入普通文件、
28
+ 命令行参数或日志作为替代方案。
29
+
30
+ 如果登录在浏览器已完成后返回 `LOGIN_PERSIST_FAILED`(详情含 `login_completed: true`),或在
31
+ 浏览器打开前返回 `LOGIN_STATE_UNAVAILABLE`,不得自动重试或再次要求扫码。先只读执行:
32
+
33
+ ```sh
34
+ nadou doctor --profile <profile> --json
35
+ nadou auth status --profile <profile> --json
36
+ ```
37
+
38
+ 修复本机 Nadou 状态目录、权限或凭据库后,才由用户或调用方显式执行下一次登录。用户明确要求
39
+ 重新登录时可以执行一次,即使当前状态为 `authenticated`;该次失败仍不得自动重试。
40
+
41
+ 登录完成后验证身份:
42
+
43
+ ```sh
44
+ nadou auth whoami --profile <profile> --json
45
+ ```
46
+
47
+ `auth status` 只检查本地凭证状态,适合常规启动检查。`auth whoami` 会访问服务端
48
+ `/apis/ping` 验证身份;该过渡接口可能更新登录时间/IP 或初始化用户和个人空间,
49
+ CLI 还会把脱敏账号和验证时间写回本地配置环境。因此它的能力副作用是
50
+ `remote_read + remote_write + local_write`,不要把它作为无副作用的高频健康探针。
51
+
52
+ ## 首次授权后的账号类型选择
53
+
54
+ 产品所说的“账号选择”是同一 Passport 登录身份下选择当前使用的个人空间或团队空间,
55
+ 不是切换多个 Passport 登录身份。首次授权成功、或本地配置环境尚未记录当前空间时,
56
+ Agent **必须先完成空间选择,再开始任何生成、扣费或画布写入**:
57
+
58
+ ```sh
59
+ nadou space list --profile <profile> --no-interactive --json
60
+ ```
61
+
62
+ 从 `space list` 的真实结果向用户列出每个候选的 `id`、名称、`type`(稳定输出为
63
+ `personal` 或 `group`,后端原始值可能是 `PERSONAL/GROUP`)和当前标记:
64
+
65
+ - 只有一个可用空间时,可记录该空间并继续,不需要多余的切换请求。
66
+ - 同时存在个人空间和团队空间,或存在多个团队空间时,必须明确询问用户选择哪一个;
67
+ 不得默认个人、默认当前标记之外的团队,也不得根据名称猜 ID。
68
+ - 用户选中的空间不是当前空间时,才执行一次 `nadou space use <space-id>`,并核对其返回的
69
+ `current` 与选择一致;返回缺失或不一致时,再用
70
+ `nadou space current --profile <profile> --no-interactive --json` 单次回读。当前空间已是用户
71
+ 选择项时不发送切换请求。
72
+ - 用户没有回答、候选数据缺失或当前空间无法核实时,停在选择步骤,不执行后续写入。
73
+
74
+ `--no-interactive` 只表示 CLI 不在终端内替用户提问;Agent 仍须把候选项和需要选择的
75
+ `space-id` 返回给调用方,等待明确选择后再执行 `space use`。不得把 Passport 登录页中的
76
+ 多账号推荐当作个人/团队空间选择,也不得通过 Passport 的账号切换接口绕过本步骤。
77
+
78
+ 后续已完成首次选择的回合只需按任务需要读取 `space current`;如果用户明确要求更换个人/
79
+ 团队空间,重新列出候选并重复上述选择与回读流程。空间选择是服务端有状态操作,成功后与
80
+ 网页端共享当前空间,写入结果未知时不得自动重试。
81
+
82
+ 退出当前配置环境:
83
+
84
+ ```sh
85
+ nadou auth logout --profile <profile> --json
86
+ ```
87
+
88
+ 显式退出会删除本机凭证,并把下一次浏览器授权标记为“重新选择账号”:下一次执行
89
+ `auth login` 时,CLI 会先清理本机回环页面上的 Passport Cookie/登录缓存,再展示登录页,
90
+ 不会静默复用上一次账号。该操作仍不承诺撤销远端会话。不要复制或展示凭证内容。
91
+ `nadou image` 和 `nadou video` 会自动检查登录状态,普通使用不必手动重复这组命令。
@@ -0,0 +1,71 @@
1
+ # 任务产物绑定契约
2
+
3
+ `canvas node attach-output` 已接入专用 `attach_task_output` 后端契约。它只接受受信任务身份与显式 selector,
4
+ 由后端创建带任务/作业/产物身份的受管 Canvas 节点;不得用通用 `CREATE_NODE.data.url`、下载重传或修改
5
+ `imageNodeOrigin`/`isCustomNode` 代替。
6
+
7
+ ## 单产物标准流程
8
+
9
+ 独立任务或不在目标画布受管空间内的任务产物,必须先复制到目标画布目录,再按复制后 `materialId` 挂载:
10
+
11
+ ```sh
12
+ nadou task outputs --task-id <task-id> --profile <profile> --compact --json
13
+
14
+ nadou space artifact deliver \
15
+ --task-id <task-id> --job-id <job-id> --output-index <output-index> \
16
+ --group-id <canvas-group-id> --directory-id <canvas-directory-id> \
17
+ --mode copy --name <label> --profile <profile> --json
18
+
19
+ nadou canvas node attach-output --canvas-id <canvas-id> \
20
+ --task-id <task-id> --selector '{"materialId":<copied-material-id>}' \
21
+ --label <label> --idempotency-key <attach-mutation-id> \
22
+ --return-snapshot --profile <profile> --json
23
+ ```
24
+
25
+ `space artifact deliver` 是独立远端写入:提交前必须明确目标空间/目录和复制副作用;它从同一
26
+ `task outputs` 唯一选择受信 URL,调用 `copy_to_space`,并用返回的新素材 ID 在目标目录回读验证。
27
+ 只有 `delivery_status=SUCCEEDED` 且 `resource.resource_id` 为正整数时,才把该值作为 attach 的
28
+ `materialId`。URL、名称、列表顺序、`assetId` 和历史节点 metadata 都不能代替复制结果。
29
+
30
+ `jobId + outputIndex` 与 `allOutputs=true` 只适用于原任务素材已经处于目标受管空间的场景;
31
+ `allOutputs=true` 不执行跨空间复制。后端返回 `failed[].errorCode=CROSS_SPACE_COPY_UNAVAILABLE` 时,
32
+ 保留每个失败 selector,停止 attach,先按上述流程复制;不得改用通用节点创建。
33
+
34
+ ## 多产物边界
35
+
36
+ 后端要求先在一次 `copy_to_space` 中批量复制全部输出,再将返回的多个 `materialId` 放入同一次 attach。
37
+ 当前 `space artifact deliver` 只支持单产物复制,因此入口 Agent 遇到多产物跨空间挂载时必须停止并报告
38
+ `FEATURE_NOT_AVAILABLE`;不得循环复制后宣称原子批量成功,也不得用 `allOutputs=true` 绕过复制。
39
+
40
+ ## Receipt 恢复
41
+
42
+ attach POST 只发送一次。仅当错误同时满足以下条件时,CLI 才在有界窗口内只读查询原 receipt:
43
+
44
+ - `operation=attach_task_output`;
45
+ - 外层 `backend_code=C00001`;
46
+ - 结构化 `backend_error_code=ATTACH_READBACK_PENDING`;
47
+ - 返回的 `workflowId + mutationId` 与原请求完全匹配。
48
+
49
+ 后端 requestId 与下游 Graph requestId 不同是正常分层,不要求相等。`receiptRevision` 与
50
+ `observedRevision` 只作为 SHA-256 一致性诊断保存,不比较大小,也不据此判断投影先后。
51
+
52
+ 符合条件后的 receipt 处理:
53
+
54
+ - `SUCCEEDED`:恢复 `attach_result`、创建节点 ID 与后端 request ID,并按成功处理;
55
+ - `INIT/PROCESSING/RETRYABLE/RECONCILING`:有限查询原 receipt;
56
+ - `NOT_FOUND` 或 workflow/mutation 身份不匹配:保持 `REQUEST_OUTCOME_UNKNOWN`,停止查询;
57
+ - `FAILED/CONFLICT/MANUAL_REVIEW`:返回权威终态;
58
+ - 窗口结束仍未收敛:保持 `REQUEST_OUTCOME_UNKNOWN`,禁止重放 POST 或更换 mutation ID。
59
+
60
+ 普通 `C00009`、`C00001`、网络 `REQUEST_OUTCOME_UNKNOWN` 不泛化为 attach receipt 轮询;`C00009` 只表示
61
+ 请求摘要不一致、真实节点内容冲突等确定性终态。
62
+
63
+ 部分成功已经落图。只有用户针对失败 selector 明确授权新的恢复写入后,才可使用新的 mutation ID 处理失败项;
64
+ 成功项不得重复挂载。
65
+
66
+ ## 依赖边与验收
67
+
68
+ attach 只建立受管结果节点,不替 Agent 猜业务来源边。成功后读取实时 Graph,确认目标节点的
69
+ `taskId/jobId/outputIndex/materialId`、`isCustomNode=false`、`imageNodeOrigin=generated` 与 URL/metadata;
70
+ 再按用户语义显式建立 `原素材 source -> attached result target`。写后再次回读并核对实际 source/target;
71
+ 任何错向、缺边或未知状态都不得宣称完成,更不得交换方向试错。
@@ -0,0 +1,65 @@
1
+ # 画布连线
2
+
3
+ 这里的“自动连线”指 Agent 识别出已确认的资产从属关系后主动提交显式边,不是 CLI 按类型猜测,也不是后端在节点创建后补边。
4
+ `canvas edge connect/patch/delete` 是 CLI 的原子连线能力:只执行请求中明确给出的关系,不替 Agent 猜测或推断业务依赖。
5
+ 完整判定、关系类型、输入映射和恢复规则见 [画布依赖图](../guides/canvas-dependency-graph.md);本页只保留命令级写入约定。
6
+ 入口 Agent 必须先根据用户目标整理依赖关系;只要一个节点产出、提供或承载的**资产**被另一个节点引用、编辑、拼接或合成,
7
+ 就必须把前者作为 `source`、后者作为 `target` 建立连线。多个片段/素材进入同一个剪辑台或合成节点时,必须逐项建立
8
+ `片段/素材 → 剪辑台/合成` 的边,不能只创建节点或只把它们摆在一起。
9
+
10
+ ## 用户语义触发矩阵
11
+
12
+ 以下表达已经明确了依赖方向,Agent 应直接把左侧节点作为 `source`、右侧节点作为 `target`,不再把“是否连线”当成另一个待确认事项:
13
+
14
+ | 用户表达 | 应建立的边 |
15
+ | --- | --- |
16
+ | “用 A 作为 B 的参考/首帧/尾帧/输入/素材” | `A -> B` |
17
+ | “A 生成后交给/流入/接到 B” | `A -> B` |
18
+ | “把 A、B 拼接/合成/剪辑/混音/导出成 C” | `A -> C`、`B -> C` |
19
+ | “把多个片段放入剪辑台/合成节点 C” | 每个片段 `-> C` |
20
+
21
+ “分组、摆放、展示、整理”只表达布局或组织关系,不建立资产依赖边。若只有节点类型、名称相似、左右位置或同画布关系,
22
+ 仍属于不明确关系,必须先询问;不能用 `parentNode` 代替 `source -> target`。
23
+
24
+ `isCustomNode=true`、`imageNodeOrigin=upload` 或同批通过 `data.url` 创建的上传/自定义素材节点不能作为
25
+ `target`。CLI 会在 Graph 写入前返回 `INVALID_EDGE_DIRECTION`、`request_sent=false`、
26
+ `automatic_fallback=false` 和 `reverse_edge_allowed=false`。Agent 不得为了让请求成功而交换 `source`/`target`;
27
+ 上传/自定义素材只能按真实依赖作为 `source`,目标必须是非自定义生成节点。若目标实际上是独立任务产物,先按
28
+ [任务产物绑定契约](canvas-attachment.md) 复制并挂载成受管生成节点,Graph 回读确认后再建立正确方向边。
29
+
30
+ ### Timeline 合成的额外门禁
31
+
32
+ Timeline 的 `materials`/`materialId`/URL 是渲染输入,不是 Graph 边。执行
33
+ `canvas media timeline web-write/export-write` 或 `canvas media export backend-submit` 前,Agent 必须读取实时 Graph,
34
+ 将每个 Timeline 素材与画布源节点按明确节点 ID、`materialId`、任务产物 URL 或唯一素材元数据匹配:
35
+
36
+ 1. 唯一匹配到已有源节点时,确认 `源节点 -> clip` 边已存在;缺失时用一次 Graph 变更补齐所有缺边。
37
+ 2. 匹配不到或匹配到多个节点时停止,报告候选和缺失事实,不按名称或位置猜测。
38
+ 3. 写后重新读取 Graph,逐条确认所有 `源节点 -> clip` 边,再继续 Timeline 写入或导出。
39
+
40
+ 例如两个 10 秒视频进入 20 秒 `clip`,即使 Timeline 已正确引用两个 URL,也必须在 Graph 中看到:
41
+
42
+ ```text
43
+ video-part-1 -> clip-20s
44
+ video-part-2 -> clip-20s
45
+ ```
46
+
47
+ Timeline 的片段先后由 `targetTimerange.start`/`duration` 表达,不能通过边的排列顺序表达;只有用户明确说“片段 2 承接片段 1”
48
+ 时,才额外建立 `片段 1 -> 片段 2`。已有完全相同的边视为已满足,不得重复创建。
49
+
50
+ 不要仅凭节点类型、标签、左右位置或同组关系猜依赖;关系不明确时先询问。`parentNode` 只表示分组层级,
51
+ 不替代资产依赖边。创建节点与依赖边时优先在同一个有序 `canvas graph mutate` 中提交;已有节点的多条边也使用一次
52
+ 有序变更。写后重新读取实时 Graph,逐条核对 `source`、`target` 和边数量;任何预期依赖缺失时停止,
53
+ 不得继续生成或导出,也不得把“节点已创建”报告为“流程已连接”。
54
+
55
+ 连接/修改的 JSON 默认通过 `--stdin` 提供嵌入文档;大批量或长载荷才用 `--body-file`。见
56
+ [canvas.md](canvas.md)。
57
+
58
+ ```sh
59
+ nadou canvas edge connect --canvas-id <canvas-id> --stdin \
60
+ --idempotency-key <new-mutation-id> --profile <profile> --json <<'EOF'
61
+ {"source":"<existing-source-node-id>","target":"<existing-target-node-id>"}
62
+ EOF
63
+ ```
64
+
65
+ 所有写操作只发送一次。结果未知时用 Graph 查询对账,不自动重试。
@@ -0,0 +1,191 @@
1
+ # 实时 Graph 写入
2
+
3
+ `canvas get` 读取实时节点和连线;`canvas graph mutate` 负责有序批量写入。
4
+ 普通发现默认用 `canvas get`;完整原始数据读取用 `canvas get --raw`;焦点邻接用 `canvas get --node-id`。
5
+
6
+ `canvas graph mutate` 接受有序 `operations`,一次请求原子提交,并使用 `mutationId` 幂等。写入结果未知时先查询对账,不自动重试;冲突也不自动重试。不得写入回调管理的 URL、`nodeStatus` 或 `taskStatus`。
7
+ 用户语义、关系类型、素材匹配、去重和环路门禁统一见 [画布依赖图](../guides/canvas-dependency-graph.md);本页补充 Graph 载荷和一次写入约束。
8
+ 普通新节点和自动布局批次使用 `--auto-layout-only`。该模式发现任何 `CREATE_NODE.position` 时整批在触网前拒绝;
9
+ 显式 `placement` 和由 CLI 补充的 placement 均合法,`PATCH_NODE.position` 不受影响。只有固定几何或 Group
10
+ 包裹等明确的高级流程才省略该开关,并保留显式坐标。
11
+ `operations` 是标准输入并保留跨类型全局顺序;CLI 只为缺少布局的 `CREATE_NODE` 注入下述稳定 placement,
12
+ 其余调用方字段保持不变。六数组形式仅作为兼容输入接受。`respectNodeLocks` 是后端服务专用字段,公网 CLI 请求必须省略;服务端在进入写入提交边界后自行启用锁保护。
13
+ CLI 在发起请求前执行后端契约的 JSON 限制:总量不超过 8 MiB、深度不超过 32、总值不超过 100000、单字符串不超过
14
+ 1000000 字节、单个键不超过 256 字节、操作不超过 1000 项。`IN_GROUP_AUTO` 只要求
15
+ `parentNode`;只有显式传入 `layout=SECTION_GRID` 时才要求 `sectionKey` 和 `columns`。
16
+ `CREATE_NODE` 未提供 `position` / `placement` 时,CLI 会补充稳定的服务端布局:普通根节点使用
17
+ `CANVAS_ORIGIN`;同批操作里有 `CREATE_EDGE` 指向该新根节点时使用 `RIGHT_OF_NODE` 和依赖源节点 ID;
18
+ 带 `parentNode` 的新子节点使用普通 `IN_GROUP_AUTO`。三种自动布局都带 `avoidCollision=true`,让服务端根据节点
19
+ 真实展示尺寸继续计算不重叠位置。`width` / `height` 必须成对且为有限正数;媒体节点应传真实展示尺寸。Graph 创建不接受
20
+ `extent`,不能把 Web/Y.Doc 展示字段带入请求。该转换不读取实时 Graph,保证相同操作的恢复载荷不因画布快照变化而漂移。
21
+
22
+ `RIGHT_OF_NODE + avoidCollision=true` 表示从锚点右侧开始寻找距离目标位置最近的空位,只保证节点不重叠,
23
+ 不保证竖直单列。同一 `anchorNodeId` 的多个节点可以形成多行多列;`gapX` / `gapY` 只改变间距,不能强制列数。
24
+ 业务必须固定为单列或其他精确几何时,调用方先读取实时 Graph,自行计算互不重叠的明确 `position`,并且不再传
25
+ `placement`;不得把自动布局的多行多列结果误报为失败,也不得通过拆分 mutation 猜测布局形状。
26
+
27
+ 同一画布中需要自动布局的多个节点必须放进同一个有序 `operations` 请求;不得按“每两个节点”等任意固定数量拆批。
28
+ 确因操作数上限或独立业务阶段无法合并的命令按画布串行。
29
+ 自动布局、相同分组/锚点或连线写不得并发;只有调用方明确提供互不重叠的 `position` 且业务意图彼此独立时才可并发。
30
+
31
+ 调用方已经提供 `position` 或 `placement` 的节点保持不变;普通 Group 子节点仅补 `IN_GROUP_AUTO`,不会猜测
32
+ `SECTION_GRID` 的 `sectionKey` / `columns`。用户语义上的依赖边仍必须显式提交,布局不会自动补边。
33
+
34
+ ## 新节点 ID
35
+
36
+ `canvas graph mutate` 中的 `CREATE_NODE` 仍要求显式 `id`,因为同一批 `CREATE_EDGE`、`parentNode`
37
+ 或布局锚点可能需要提前引用它。Agent 必须在组装操作前为每个新节点调用:
38
+
39
+ ```sh
40
+ nadou canvas node new-id --json
41
+ ```
42
+
43
+ 保存响应的 `data.node_id` 并填入节点及其所有引用位置。不要用标签生成 `explicit-flow-brief`、
44
+ `recipe-hero-shot` 等语义 ID,也不要自行拼接时间戳/随机串。下文 JSON 中的 `<...-node-id>` 都表示
45
+ 由该命令实际返回的值。已有 Graph 节点的历史 ID 不受新生成规则影响,必须原样使用。
46
+
47
+ ## 写前读取 → 单次写入 → 写后回读
48
+
49
+ 这是 Agent 的显式编排,不是 CLI 暗中增加的请求:
50
+
51
+ ```sh
52
+ nadou canvas get --canvas-id <canvas-id> --summary --profile <profile> --json
53
+ nadou canvas graph mutate --canvas-id <canvas-id> \
54
+ --auto-layout-only --idempotency-key <new-mutation-id> --stdin --profile <profile> --json
55
+ nadou canvas get --canvas-id <canvas-id> --summary --profile <profile> --json
56
+ ```
57
+
58
+ 写前记录现有节点和边,按用户明确计划构造一次变更;写后逐项核对请求中的节点、参数、边和依赖。
59
+ 任何一项缺失、多出或指向错误时,都不得继续下游任务或宣称画布已完成。写响应
60
+ 包含快照时可先核对该快照;结果不完整或不确定时仍需显式读取实时 Graph。
61
+
62
+ ## 资产从属关系:Agent 必须显式建边
63
+
64
+ CLI 不根据节点类型、名称或位置自动推断连线,但这不意味着可以省略有业务意义的依赖边。入口 Agent
65
+ 在写入前必须把用户目标翻译成依赖图:节点 A 产出、提供或承载的资产被节点 B 引用、编辑、拼接或合成时,
66
+ 建立 `A -> B` 的 `CREATE_EDGE`。例如“两个 10 秒片段进入 20 秒合成/剪辑台”必须包含两条边:
67
+
68
+ ```text
69
+ 片段 1 -> 合成节点
70
+ 片段 2 -> 合成节点
71
+ ```
72
+
73
+ 对应的 Graph 操作至少包含以下两条边(节点 ID 必须来自写前读取或同批创建):
74
+
75
+ ```json
76
+ [
77
+ {"type":"CREATE_EDGE","edge":{"source":"<existing-segment-node-id-1>","target":"<existing-composition-node-id>"}},
78
+ {"type":"CREATE_EDGE","edge":{"source":"<existing-segment-node-id-2>","target":"<existing-composition-node-id>"}}
79
+ ]
80
+ ```
81
+
82
+ 这条规则适用于参考图、首尾帧、音视频素材、分段片段和合成输入;仅仅同组、相邻摆放、名称相似或
83
+ 共享一个画布不构成依赖。`parentNode` 表达分组层级,不能替代资产依赖边。
84
+
85
+ 执行时遵循以下门禁:
86
+
87
+ 1. 先读取实时 Graph,确认每个源节点、目标节点和已有边的真实 ID;关系方向不清楚时先询问,不按类型或标签猜。
88
+ 2. 创建节点与依赖边时,将 `CREATE_NODE` 放在前面、`CREATE_EDGE` 放在后面,放入同一个有序变更;已有节点的多条边也优先一次提交。
89
+ 3. 写后重新读取实时 Graph,逐条核对期望的 `source`、`target` 和边数量;缺边、错边或结果不确定时停止,不得继续生成/导出或自动补写。
90
+
91
+ 只有用户目标或产品规则已经确认依赖关系时才建立这些边;Agent 不得为了“看起来完整”给无关节点增加边。已经存在的完全相同边
92
+ 视为满足,不得重复创建;Timeline 的片段顺序不由 Graph 边顺序表达。
93
+
94
+ ### 从用户目标生成依赖图
95
+
96
+ “自动”只表示 Agent 根据已明确的用户语义主动调用显式连线命令,不表示 CLI 根据节点类型或位置猜边。以下关系可直接视为已确认:
97
+
98
+ - 参考、首帧、尾帧、输入、素材、前置、交给、流入:左侧资产 `->` 右侧消费节点;
99
+ - 拼接、合成、剪辑、混音、导出成:每个列出的输入资产 `->` 结果节点;
100
+ - 多个片段放入剪辑台或 `clip`:每个片段 `-> clip`。
101
+
102
+ 对于已经存在的 Timeline,`materials` 中的素材只有在按节点 ID、`materialId`、任务产物 URL 或唯一素材元数据
103
+ 匹配到源节点后,才能确认对应的 `源节点 -> clip` 边;Timeline 引用本身不能代替 Graph 边。匹配唯一但 Graph 缺边时,
104
+ 先用一次变更补齐并写后回读;匹配不到或有多个候选时停止,不按标签、位置或类型猜测。
105
+
106
+ 下面是一个只包含三节点、两条显式依赖的最小结构示例;CLI 不根据节点类型推断额外连线:
107
+
108
+ ```json
109
+ [
110
+ {"type":"CREATE_NODE","node":{"id":"<brief-node-id>","type":"text","data":{"label":"镜头简报"}}},
111
+ {"type":"CREATE_NODE","node":{"id":"<image-node-id>","type":"image","data":{"label":"关键画面"}}},
112
+ {"type":"CREATE_NODE","node":{"id":"<video-node-id>","type":"video","data":{"label":"成片镜头"}}},
113
+ {"type":"CREATE_EDGE","edge":{"source":"<brief-node-id>","target":"<image-node-id>"}},
114
+ {"type":"CREATE_EDGE","edge":{"source":"<image-node-id>","target":"<video-node-id>"}}
115
+ ]
116
+ ```
117
+
118
+ 该批次使用 `--auto-layout-only`:CLI 会为首个根节点补 `CANVAS_ORIGIN`,并根据同批依赖边为后续节点补
119
+ `RIGHT_OF_NODE`;Agent 不读取 Graph 后生成固定坐标。
120
+
121
+ 仅在用户目标或产品规则确认这两条依赖时提交该 JSON。若依赖方向、节点身份或目标画布不明确,先询问,
122
+ 不要把示例当作无条件通用工作流。
123
+
124
+ ## 结构画布:一次原子写入示例
125
+
126
+ 以下示例只建立一个短片前期规划的结构画布:一个分组、四个子节点和四条依赖连线;它不代表图片、音频或视频已经生成。仅在用户明确指定空白、可丢弃的测试画布时使用。写前先读取实时图:
127
+
128
+ ```sh
129
+ nadou canvas get --canvas-id <canvas-id> --summary \
130
+ --profile <profile> --no-interactive --json
131
+ ```
132
+
133
+ 把下面的操作作为一次、不可重排的 Graph 写入;固定节点 ID 在同一画布只能创建一次。
134
+ 默认通过 `--stdin` 提供嵌入文档;操作很长、需留盘复现或反复对账时再改用 `--body-file`:
135
+
136
+ ```sh
137
+ nadou canvas graph mutate --canvas-id <canvas-id> \
138
+ --idempotency-key <new-stable-mutation-id> --return-snapshot --stdin \
139
+ --profile <profile> --no-interactive --json <<'EOF'
140
+ [
141
+ {"type":"CREATE_NODE","node":{"id":"<group-node-id>","type":"group","position":{"x":0,"y":0},"data":{"label":"短片结构"}}},
142
+ {"type":"CREATE_NODE","node":{"id":"<story-node-id>","type":"text","parentNode":"<group-node-id>","placement":{"mode":"IN_GROUP_AUTO","layout":"SECTION_GRID","sectionKey":"scenes","columns":3,"gapX":32,"gapY":32,"avoidCollision":true},"data":{"label":"故事节拍","text":"在这里填写故事节拍正文。","prompt":""}}},
143
+ {"type":"CREATE_NODE","node":{"id":"<image-node-id>","type":"image","parentNode":"<group-node-id>","placement":{"mode":"IN_GROUP_AUTO","layout":"SECTION_GRID","sectionKey":"characters","columns":3,"gapX":32,"gapY":32,"avoidCollision":true},"data":{"label":"主视觉"}}},
144
+ {"type":"CREATE_NODE","node":{"id":"<audio-node-id>","type":"audio","parentNode":"<group-node-id>","placement":{"mode":"IN_GROUP_AUTO","layout":"SECTION_GRID","sectionKey":"items","columns":3,"gapX":32,"gapY":32,"avoidCollision":true},"data":{"label":"氛围声音"}}},
145
+ {"type":"CREATE_NODE","node":{"id":"<video-node-id>","type":"video","parentNode":"<group-node-id>","placement":{"mode":"IN_GROUP_AUTO","layout":"SECTION_GRID","sectionKey":"scenes","columns":3,"gapX":32,"gapY":32,"avoidCollision":true},"data":{"label":"主镜头"}}},
146
+ {"type":"CREATE_EDGE","edge":{"source":"<story-node-id>","target":"<image-node-id>"}},
147
+ {"type":"CREATE_EDGE","edge":{"source":"<story-node-id>","target":"<video-node-id>"}},
148
+ {"type":"CREATE_EDGE","edge":{"source":"<image-node-id>","target":"<video-node-id>"}},
149
+ {"type":"CREATE_EDGE","edge":{"source":"<audio-node-id>","target":"<video-node-id>"}}
150
+ ]
151
+ EOF
152
+ ```
153
+
154
+ `--return-snapshot` 只用于同一次写响应中的完整图验收;普通发现仍使用 `canvas get` 或 `canvas get --summary`。保存画布 ID、变更 ID 和请求 ID。若响应没有可确认的完整快照,再读取实时 Graph 核对结构;只能报告“结构画布已建立”,不能报告媒体已生成。
155
+
156
+ ## 已有节点打组的几何规则
157
+
158
+ Graph 中根节点的 `position` 是画布坐标;节点挂入 `parentNode` 后,子节点的 `position` 会被解释为**相对父分组的坐标**。因此,不能只给已有节点补 `rootPatch.parentNode`:如果继续发送它们原来的根坐标,节点会相对父分组再平移一次,常见结果是左侧或顶部节点跑出边框。
159
+
160
+ 打组前必须先用一次完整的 `canvas get --raw` 读取所选节点的实时 `position`、`width` 和 `height`,并按以下顺序构造同一批有序操作:
161
+
162
+ 1. 用所有被选节点的画布坐标和尺寸计算联合边界:
163
+ `minX = min(x)`、`minY = min(y)`、`maxX = max(x + width)`、`maxY = max(y + height)`。分组的 `position`、`width`、`height` 必须覆盖这块边界;需要留白时,使用调用方明确给出的留白值,不能凭节点类型猜尺寸。
164
+ 2. 先用 `CREATE_NODE` 创建新分组,再为每个已有节点发送 `PATCH_NODE`。除 `rootPatch.parentNode` 外,必须同时发送相对坐标:
165
+ `rootPatch.position.x = childAbsoluteX - groupX`、
166
+ `rootPatch.position.y = childAbsoluteY - groupY`。不要把原始根坐标直接复制到组内。
167
+ 3. 不要用 `IN_GROUP_AUTO` 替代已有节点的相对坐标转换;该布局只适合新建子节点交给服务端自动布局。已有节点的 `width`、`height` 和其他未修改字段保持读取到的值。
168
+
169
+ 例如,实时读取到一个已有节点画布坐标 `(-102.5, 342)`,新分组位置为 `(-140, -40)`,则挂组修改必须使用 `position: {"x":37.5,"y":382}`,而不是继续使用 `(-102.5,342)`。写入仍只发送一次;成功后用返回快照或再次 `canvas get --raw` 计算子节点的绝对坐标,确认每个节点的右下边界都在分组内。边界不完整、尺寸字段缺失或结果未知时,停止并报告差异,不自动重放变更。
170
+
171
+ ## 依赖既有状态的安全修改与恢复
172
+
173
+ 修改既有节点,特别是嵌套业务对象前,先读取实时完整图并保留相关对象的完整同级字段。`dataPatch` 是浅合并,不能只猜测或写入一个深层字段。
174
+
175
+ 短修改仍用 `--stdin`;从快照整理出的长操作再落盘并用 `--body-file`:
176
+
177
+ ```sh
178
+ nadou canvas get --canvas-id <canvas-id> --raw \
179
+ --profile <profile> --no-interactive --json
180
+ nadou canvas graph mutate --canvas-id <canvas-id> \
181
+ --idempotency-key <new-stable-mutation-id> --body-file revised-operations.json \
182
+ --profile <profile> --no-interactive --json
183
+ ```
184
+
185
+ | 结果 | 必须采取的动作 |
186
+ | --- | --- |
187
+ | `REQUEST_OUTCOME_UNKNOWN` | CLI 会在有界窗口内只读查询原变更 ID 的 receipt,但不会再发写请求。若窗口结束仍未知,保留原变更 ID、原载荷、画布 ID 和请求 ID,执行返回的精确 `canvas node mutation-status` 命令继续对账;不得依据 Graph 暂未出现目标而重写。仅在 receipt 明确证明未应用后,才可显式复用原变更 ID 和完全相同的载荷。 |
188
+ | `CANVAS_CONFLICT` | 不要自动重试或按错误文本猜测原因。实时查询后由调用方决定是否重建内容;内容改变时必须使用新的变更 ID。 |
189
+ | 本地校验或后端拒绝 | 修正可见内容后再提交;不得通过补写模型参数结构、任务状态或内部字段绕过规则。 |
190
+
191
+ 恢复和验证使用 `canvas get`。不得为了自动清理删除分组;删除分组会递归删除全部子节点,必须由用户明确确认。