@ohos-cpf/3rdloop 0.0.11 → 0.0.13

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 (46) hide show
  1. package/lib/cli.js +2 -2
  2. package/package.json +1 -1
  3. package/vendor/Server/Routes/controllers/LoopEngineController.js +36 -3
  4. package/vendor/Server/Routes/controllers/OrchestratorController.js +193 -9
  5. package/vendor/Server/Skills/flutter-build-test/SKILL.md +252 -0
  6. package/vendor/Server/Skills/flutter-build-test/assets/BUILDENV_TEMPLATE.md +42 -0
  7. package/vendor/Server/Skills/flutter-build-test/assets/BUILD_REPORT_TEMPLATE.md +64 -0
  8. package/vendor/Server/Skills/flutter-build-test/assets/README_SECTION_TEMPLATE.md +78 -0
  9. package/vendor/Server/Skills/flutter-build-test/references/BUILD_TROUBLESHOOTING.md +128 -0
  10. package/vendor/Server/Skills/flutter-build-test/references/DOC_UPDATE_GUIDE.md +119 -0
  11. package/vendor/Server/Skills/flutter-build-test/references/FLVM_GUIDE.md +89 -0
  12. package/vendor/Server/Skills/flutter-build-test/scripts/build-matrix.cjs +374 -0
  13. package/vendor/Server/Skills/flutter-build-test/scripts/locate-example.cjs +189 -0
  14. package/vendor/Server/Skills/flutter-build-test/scripts/update-buildenv.cjs +171 -0
  15. package/vendor/Server/Skills/flutter-code-use/SKILL.md +316 -0
  16. package/vendor/Server/Skills/flutter-code-use/references/event-channel.md +440 -0
  17. package/vendor/Server/Skills/flutter-code-use/references/federated.md +295 -0
  18. package/vendor/Server/Skills/flutter-code-use/references/ffi-binding-translate.md +130 -0
  19. package/vendor/Server/Skills/flutter-code-use/references/ffi-compile-from-source.md +169 -0
  20. package/vendor/Server/Skills/flutter-code-use/references/ffi-fetch-at-build.md +161 -0
  21. package/vendor/Server/Skills/flutter-code-use/references/ffi-prebuilt-bundle.md +175 -0
  22. package/vendor/Server/Skills/flutter-code-use/references/ffi-rhttp-guide.md +235 -0
  23. package/vendor/Server/Skills/flutter-code-use/references/ffi-rust-cross-compile.md +514 -0
  24. package/vendor/Server/Skills/flutter-code-use/references/ffi.md +220 -0
  25. package/vendor/Server/Skills/flutter-code-use/references/method-channel.md +643 -0
  26. package/vendor/Server/Skills/flutter-code-use/references/monorepo.md +188 -0
  27. package/vendor/Server/Skills/flutter-code-use/references/ohos-api-pitfalls.md +717 -0
  28. package/vendor/Server/Skills/flutter-code-use/references/platform-view.md +448 -0
  29. package/vendor/Server/Skills/flutter-code-use/references/pure-dart.md +180 -0
  30. package/vendor/Server/Skills/flutter-code-use/references/texture.md +459 -0
  31. package/vendor/Server/Skills/flutter-demo-code-generator/SKILL.md +270 -0
  32. package/vendor/Server/Skills/flutter-demo-code-generator/assets/PAGE_TEMPLATES.md +544 -0
  33. package/vendor/Server/Skills/flutter-demo-code-generator/references/CODE_STANDARDS.md +328 -0
  34. package/vendor/Server/Skills/flutter-demo-code-generator/references/DEMO_DOC_PARSING.md +126 -0
  35. package/vendor/Server/Skills/flutter-demo-code-generator/references/EXAMPLES.md +629 -0
  36. package/vendor/Server/Skills/flutter-demo-code-generator/scripts/validate-flutter-demo.cjs +268 -0
  37. package/vendor/Server/Skills/flutter-demo-doc-generator/SKILL.md +227 -0
  38. package/vendor/Server/Skills/flutter-demo-doc-generator/assets/DEMO_DOC_TEMPLATE.md +78 -0
  39. package/vendor/Server/Skills/flutter-demo-doc-generator/references/COVERAGE_REPORT_PARSING.md +174 -0
  40. package/vendor/Server/Skills/flutter-demo-doc-generator/references/EXAMPLES.md +162 -0
  41. package/vendor/Server/Skills/flutter-demo-doc-generator/references/MCP_TOOL_GUIDE.md +123 -0
  42. package/vendor/Server/Skills/flutter-demo-doc-generator/references/OUTPUT_FORMAT.md +190 -0
  43. package/vendor/Server/Skills/flutter-demo-doc-generator/references/QUALITY_CHECKLIST.md +83 -0
  44. package/vendor/Server/Skills/flutter-demo-doc-generator/scripts/validate-skill.cjs +259 -0
  45. package/vendor/Server/Skills/flutter-library-demo-coverage/SKILL.md +175 -0
  46. package/vendor/VERSION +3 -3
@@ -0,0 +1,328 @@
1
+ # Flutter Demo 代码规范速查
2
+
3
+ 本文档为 `flutter-demo-code-generator` 技能的代码生成提供规范速查,涵盖命名规则、Dart 最佳实践、日志规范、错误处理模式等。
4
+
5
+ ---
6
+
7
+ ## 一、文件命名规范
8
+
9
+ ### 目录命名
10
+
11
+ 格式:`{三位序号}_{snake_case功能描述}`
12
+
13
+ | 规则 | 说明 | 示例 |
14
+ |------|------|------|
15
+ | 三位序号 | 用零补齐,保证目录排序与 Demo 序号一致 | `001`、`012`、`100` |
16
+ | snake_case 描述 | 全小写字母,单词间用下划线,3-5 个单词 | `check_support_and_config` |
17
+ | 完整目录名 | `{序号}_{描述}` | `001_check_support_and_config` |
18
+
19
+ ### Dart 文件命名
20
+
21
+ 格式:`{snake_case功能描述}_page.dart`
22
+
23
+ | Demo 中文名 | 目录名 | 文件名 | 类名 |
24
+ |-----------|-------|--------|------|
25
+ | 环境检测与版本查询 Demo | `001_check_support` | `check_support_page.dart` | `CheckSupportPage` |
26
+ | 控制器初始化与资源释放 Demo | `002_controller_lifecycle` | `controller_lifecycle_page.dart` | `ControllerLifecyclePage` |
27
+ | 播放控制与进度管理 Demo | `003_playback_control` | `playback_control_page.dart` | `PlaybackControlPage` |
28
+ | 音量控制 Demo | `004_volume_control` | `volume_control_page.dart` | `VolumeControlPage` |
29
+
30
+ ### 辅助文件命名(可选)
31
+
32
+ 若 Demo 需要独立的数据类或辅助 Widget:
33
+ - 数据类:`{snake_case名}_model.dart`
34
+ - 辅助 Widget:`{snake_case名}_widget.dart`
35
+
36
+ ---
37
+
38
+ ## 二、Dart/Flutter 编码规范
39
+
40
+ ### 2.1 类型声明
41
+
42
+ ```dart
43
+ // ✅ 优先使用具体类型,避免 dynamic
44
+ final String result = library.getVersion();
45
+ final List<String> items = [];
46
+ final Map<String, int> counts = {};
47
+
48
+ // ✅ 泛型参数完整声明
49
+ final StreamController<PlaybackEvent> _controller = StreamController<PlaybackEvent>();
50
+
51
+ // ❌ 避免 dynamic(除非确实无法确定类型)
52
+ dynamic result = library.something(); // 避免
53
+ ```
54
+
55
+ ### 2.2 Null Safety
56
+
57
+ ```dart
58
+ // ✅ 可空类型声明
59
+ SomeController? _controller;
60
+
61
+ // ✅ 安全访问
62
+ _controller?.dispose();
63
+
64
+ // ✅ 空值合并
65
+ final text = _resultText ?? '(暂无结果)';
66
+
67
+ // ✅ 非空断言(仅在确定不为空的场景使用)
68
+ _controller!.play(); // 仅在已验证 _controller != null 后使用
69
+ ```
70
+
71
+ ### 2.3 const 优化(强制要求)
72
+
73
+ ```dart
74
+ // ✅ 不依赖运行时状态的 Widget 必须用 const
75
+ const Text('固定标题'),
76
+ const SizedBox(height: 16),
77
+ const Divider(),
78
+ const CircleAvatar(child: Text('01')),
79
+
80
+ // ✅ 构造函数也应声明 const(当所有字段都是编译期常量时)
81
+ class DemoButton extends StatelessWidget {
82
+ const DemoButton({super.key, required this.label, required this.onPressed});
83
+ // ...
84
+ }
85
+
86
+ // ❌ 有状态 Widget 不能用 const
87
+ const Text(_resultText), // ❌ _resultText 是变量
88
+ ```
89
+
90
+ ### 2.4 setState 最佳实践
91
+
92
+ ```dart
93
+ // ✅ 合并多个状态更新到一次 setState()
94
+ setState(() {
95
+ _isLoading = false;
96
+ _resultText = '结果:$result';
97
+ _callbackCount++;
98
+ });
99
+
100
+ // ❌ 避免多次连续 setState()(每次都触发重建)
101
+ setState(() => _isLoading = false);
102
+ setState(() => _resultText = '结果:$result'); // 避免
103
+
104
+ // ✅ 检查 mounted 后再调用 setState(异步回调中)
105
+ void _onAsyncCallback(String result) {
106
+ if (!mounted) return; // 页面已销毁,不再更新
107
+ setState(() => _resultText = result);
108
+ }
109
+ ```
110
+
111
+ ### 2.5 Widget 提取规范
112
+
113
+ ```dart
114
+ // ✅ 将重复使用或复杂的 Widget 抽取为方法或独立类
115
+ Widget _buildResultArea() {
116
+ if (_isLoading) {
117
+ return const Center(child: CircularProgressIndicator());
118
+ }
119
+ return Container(
120
+ padding: const EdgeInsets.all(12),
121
+ decoration: BoxDecoration(
122
+ color: Colors.grey[100],
123
+ borderRadius: BorderRadius.circular(8),
124
+ ),
125
+ child: SelectableText(_resultText.isEmpty ? '(暂无结果)' : _resultText),
126
+ );
127
+ }
128
+ ```
129
+
130
+ ---
131
+
132
+ ## 三、日志规范
133
+
134
+ ### 3.1 Tag 命名
135
+
136
+ ```dart
137
+ // ✅ 每个文件有独立的日志 Tag 常量
138
+ const String _kTag = 'FlutterVideoPlayer_CheckSupportPage';
139
+
140
+ // Tag 命名规则:{LibraryName}_{ComponentName}
141
+ // - 不超过 40 字符
142
+ // - 只含字母、数字、下划线
143
+ // - LibraryName:包名去掉前缀下划线,使用 UpperCamelCase(如 FlutterVideoPlayer)
144
+ // - ComponentName:页面组件名(如 CheckSupportPage)
145
+ ```
146
+
147
+ ### 3.2 日志函数使用
148
+
149
+ ```dart
150
+ import 'dart:developer' as dev;
151
+
152
+ // ✅ INFO 级别:重要操作成功、页面生命周期
153
+ dev.log('Page appeared', name: _kTag);
154
+ dev.log('_initController succeeded', name: _kTag);
155
+
156
+ // ✅ DEBUG 级别:方法入口、中间步骤
157
+ dev.log('_checkSupport called', name: _kTag);
158
+ dev.log('Volume set to: $volume', name: _kTag);
159
+
160
+ // ✅ ERROR 级别:捕获异常(必须传 error 和 stackTrace)
161
+ dev.log('_initController failed', name: _kTag, error: e, stackTrace: stack);
162
+
163
+ // ✅ 敏感信息不应以明文输出(例如用户 token、账号)
164
+ // dev.log('Token: $token', name: _kTag); // ❌ 安全违规
165
+ ```
166
+
167
+ ### 3.3 必须添加日志的位置
168
+
169
+ | 位置 | 说明 | 示例 |
170
+ |------|------|------|
171
+ | `initState()` | 页面出现 | `dev.log('Page appeared', name: _kTag)` |
172
+ | `dispose()` | 页面销毁 | `dev.log('Page disposed', name: _kTag)` |
173
+ | 每个操作方法入口 | 调用前记录 | `dev.log('_play called', name: _kTag)` |
174
+ | 接口调用成功 | 记录关键返回值 | `dev.log('initialized, duration: $duration', name: _kTag)` |
175
+ | 捕获到异常 | 传 error 和 stackTrace | `dev.log('failed', name: _kTag, error: e, stackTrace: stack)` |
176
+ | 重要状态变化 | 监听回调中 | `dev.log('Playback state: $state', name: _kTag)` |
177
+
178
+ ---
179
+
180
+ ## 四、错误处理规范
181
+
182
+ ### 4.1 异步接口标准模式
183
+
184
+ ```dart
185
+ /// 初始化控制器(异步模式标准模板)
186
+ Future<void> _initController() async {
187
+ dev.log('_initController called', name: _kTag);
188
+ setState(() => _isLoading = true);
189
+ try {
190
+ await _controller.initialize();
191
+ dev.log('_initController succeeded', name: _kTag);
192
+ if (!mounted) return; // 页面可能已销毁,不再更新状态
193
+ setState(() {
194
+ _status = '已初始化';
195
+ _isLoading = false;
196
+ });
197
+ } catch (e, stack) {
198
+ dev.log('_initController failed', name: _kTag, error: e, stackTrace: stack);
199
+ if (!mounted) return;
200
+ setState(() {
201
+ _status = '初始化失败:$e';
202
+ _isLoading = false;
203
+ });
204
+ }
205
+ }
206
+ ```
207
+
208
+ ### 4.2 同步接口标准模式
209
+
210
+ ```dart
211
+ /// 检测设备支持(同步模式标准模板)
212
+ void _checkSupport() {
213
+ dev.log('_checkSupport called', name: _kTag);
214
+ try {
215
+ final isSupported = LibraryUtils.isHardwareDecodingSupported();
216
+ dev.log('_checkSupport result: $isSupported', name: _kTag);
217
+ setState(() {
218
+ _supportText = isSupported ? '支持硬件解码 ✅' : '不支持硬件解码 ❌';
219
+ });
220
+ } catch (e, stack) {
221
+ dev.log('_checkSupport failed', name: _kTag, error: e, stackTrace: stack);
222
+ setState(() => _supportText = '检测失败:$e');
223
+ }
224
+ }
225
+ ```
226
+
227
+ ### 4.3 Navigator 错误处理(不抛异常,不需要 try/catch)
228
+
229
+ ```dart
230
+ // ✅ Navigator.push 用 await 捕获返回结果即可
231
+ // Flutter Navigator 不抛出异常(除非路由配置错误)
232
+ Navigator.push(
233
+ context,
234
+ MaterialPageRoute(builder: (_) => const SomePage()),
235
+ );
236
+ ```
237
+
238
+ ---
239
+
240
+ ## 五、资源生命周期管理
241
+
242
+ 所有持有的资源必须在 `dispose()` 中释放:
243
+
244
+ ```dart
245
+ // 声明(在 State 类中,非 @override 变量)
246
+ SomeController? _controller;
247
+ StreamSubscription<SomeEvent>? _subscription;
248
+ Timer? _timer;
249
+
250
+ @override
251
+ void dispose() {
252
+ dev.log('Page disposed, releasing resources', name: _kTag);
253
+
254
+ // 释放三方库实例
255
+ _controller?.dispose();
256
+ _controller = null;
257
+
258
+ // 取消 Stream 订阅
259
+ _subscription?.cancel();
260
+ _subscription = null;
261
+
262
+ // 清除定时器
263
+ _timer?.cancel();
264
+ _timer = null;
265
+
266
+ super.dispose(); // 必须在最后调用
267
+ }
268
+ ```
269
+
270
+ ---
271
+
272
+ ## 六、双计数器诊断模式
273
+
274
+ 对涉及回调/事件的异步链路,规划双计数器帮助诊断:
275
+
276
+ ```dart
277
+ // 计数器状态变量(必须在 setState() 中更新)
278
+ int _triggerCount = 0; // 触发/调用次数
279
+ int _callbackCount = 0; // 回调实际被调用次数
280
+
281
+ // 触发操作
282
+ void _triggerAction() {
283
+ dev.log('_triggerAction called', name: _kTag);
284
+ setState(() => _triggerCount++);
285
+ library.doSomething();
286
+ }
287
+
288
+ // 回调处理
289
+ void _onCallback(SomeEvent event) {
290
+ dev.log('Callback received: $event', name: _kTag);
291
+ if (!mounted) return;
292
+ setState(() {
293
+ _callbackCount++;
294
+ _lastEvent = event.toString();
295
+ });
296
+ }
297
+
298
+ // UI 展示(诊断区域)
299
+ Widget _buildDiagnosticArea() {
300
+ return Column(
301
+ children: [
302
+ Text('触发次数: $_triggerCount'),
303
+ Text('回调次数: $_callbackCount'),
304
+ if (_triggerCount > 0 && _callbackCount == 0)
305
+ const Text('⚠️ 已触发但回调未收到,请检查监听注册', style: TextStyle(color: Colors.orange)),
306
+ if (_callbackCount > 0 && _triggerCount == _callbackCount)
307
+ const Text('✅ 链路正常', style: TextStyle(color: Colors.green)),
308
+ ],
309
+ );
310
+ }
311
+ ```
312
+
313
+ ---
314
+
315
+ ## 七、常见 pubspec.yaml 依赖示例
316
+
317
+ ```yaml
318
+ dependencies:
319
+ flutter:
320
+ sdk: flutter
321
+ # 三方库(根据实际情况填写)
322
+ flutter_video_player: ^1.0.0
323
+
324
+ dev_dependencies:
325
+ flutter_test:
326
+ sdk: flutter
327
+ flutter_lints: ^3.0.0
328
+ ```
@@ -0,0 +1,126 @@
1
+ # Demo 描述文档解析规范
2
+
3
+ > 本文档定义 `flutter-demo-code-generator` 技能的输入文档解析规则:字段映射、接口签名解析、中文→英文命名推导、步骤→UI 控件映射。
4
+
5
+ ---
6
+
7
+ ## 1. 文档定位
8
+
9
+ | 属性 | 说明 |
10
+ |------|------|
11
+ | 文件名模式 | `*Flutter测试demo描述.md` |
12
+ | 产出方 | 通常由 Demo 描述文档生成技能(上游)产出 |
13
+ | 典型结构 | 库基本信息 → 测试 Demo 描述列表(表格)→ 接口覆盖矩阵 |
14
+
15
+ ---
16
+
17
+ ## 2. Demo 条目表字段映射
18
+
19
+ | 文档字段 | 用途 |
20
+ |----------|------|
21
+ | 序号 | 目录序号(三位补零,如 `1` → `001`) |
22
+ | 测试 Demo 名称(中文) | 导航卡片 `title`、页面 AppBar 标题 `[{序号}] {名称}` |
23
+ | 测试 Demo 描述 | 导航卡片 `description`(≤40字)+ 页面说明卡片文案 |
24
+ | 测试 Demo 步骤 | 页面操作区设计依据:**每一步映射为一个控件/按钮** |
25
+ | 测试 Demo 预期结果 | 结果展示区文案与成功/失败判定提示 |
26
+ | 对应函数接口 | 文件头 Dart doc 注释 + 页面内实际调用的接口清单 |
27
+
28
+ ---
29
+
30
+ ## 3. 接口签名解析规则
31
+
32
+ 描述文档中的接口签名格式及对应的生成模式:
33
+
34
+ | 签名形式 | 示例 | 生成模式 |
35
+ |----------|------|----------|
36
+ | 顶层函数 | `getSDKVersion(): String` | 直接调用;无 `Future` → **同步模式** |
37
+ | 顶层异步函数 | `loadConfig(): Future<Map>` | 直接调用 → **异步模式** |
38
+ | 类方法 | `controller.play(): void` | 需先构造实例(本页 init 或独立初始化 Demo 提供) |
39
+ | 类异步方法 | `controller.initialize(): Future<void>` | **异步模式** + mounted 检查 |
40
+ | 构造函数 | `VideoPlayerController(config)` | 生成实例化调用,参数按签名构造 |
41
+ | 事件流/监听 | `onPlaybackState.listen`、`addListener(callback)` | **监听器模式**(StreamSubscription + 双计数器) |
42
+
43
+ **参数解析**:签名中的可选参数(`{autoPlay, initialVolume}`)生成默认值调用,并在行内注释说明可调参数。
44
+
45
+ ---
46
+
47
+ ## 4. 中文名 → 英文命名推导
48
+
49
+ ### 4.1 推导流程
50
+
51
+ ```
52
+ 中文名称 → 提取核心功能词 → 翻译为英文(3-5 个单词)
53
+ → snake_case → 目录名 / 文件名
54
+ → UpperCamelCase + Page → 类名
55
+ ```
56
+
57
+ ### 4.2 推导示例
58
+
59
+ | 中文名 | 功能词 | 目录名 | 文件名 | 类名 |
60
+ |--------|--------|--------|--------|------|
61
+ | 环境检测与版本查询 Demo | check support | `001_check_support` | `check_support_page.dart` | `CheckSupportPage` |
62
+ | 控制器初始化与资源释放 Demo | controller lifecycle | `002_controller_lifecycle` | `controller_lifecycle_page.dart` | `ControllerLifecyclePage` |
63
+ | 播放控制与进度管理 Demo | playback control | `003_playback_control` | `playback_control_page.dart` | `PlaybackControlPage` |
64
+ | 音量控制 Demo | volume control | `004_volume_control` | `volume_control_page.dart` | `VolumeControlPage` |
65
+
66
+ ### 4.3 约束
67
+
68
+ - 同一描述文档内目录名、类名**不得重复**
69
+ - 仅使用小写字母、数字、下划线(目录/文件),不得含中文拼音混排
70
+ - 序号必须三位数字(`001`、`010`、`100`),保证文件系统排序与 Demo 序号一致
71
+
72
+ ---
73
+
74
+ ## 5. 步骤 → UI 控件映射规则
75
+
76
+ | 步骤动作词 | 生成控件 |
77
+ |-----------|----------|
78
+ | 点击 / 按下 / 触发 | `ElevatedButton` / `IconButton` |
79
+ | 输入 / 设置 / 填写 URL | `TextField`(含 `TextEditingController`,dispose 中释放) |
80
+ | 调节 / 滑动(音量/进度) | `Slider`(onChanged 中调用 set 接口) |
81
+ | 开关 / 切换 | `Switch` / `Checkbox` |
82
+ | 等待 / 加载 | `CircularProgressIndicator` + 状态文案(异步模式自动携带) |
83
+ | 观察 / 查看 / 验证 | 结果展示区(`SelectableText`)或双计数器诊断区 |
84
+
85
+ **步骤依赖处理**:当步骤存在先后依赖(如"先初始化,再播放"),用页面状态变量控制按钮可用性(初始化完成前播放按钮 `onPressed: null`)。
86
+
87
+ ---
88
+
89
+ ## 6. 文件规划表模板
90
+
91
+ Phase 1.3 使用(内部工作记录,不写入输出):
92
+
93
+ ```
94
+ 文件规划:
95
+ ┌──────────────────────────────────────────────────────────────────┐
96
+ │ 主入口:lib/main.dart │
97
+ │ 主导航页:lib/pages/demo_home_page.dart │
98
+ │ │
99
+ │ Demo 页面列表(按序号): │
100
+ │ lib/pages/001_check_support/ │
101
+ │ check_support_page.dart → Demo 1:环境检测(同步模式) │
102
+ │ lib/pages/002_controller_lifecycle/ │
103
+ │ controller_lifecycle_page.dart → Demo 2:生命周期(异步模式) │
104
+ │ lib/pages/003_playback_control/ │
105
+ │ playback_control_page.dart → Demo 3:播放控制(监听模式) │
106
+ │ ... │
107
+ └──────────────────────────────────────────────────────────────────┘
108
+
109
+ 接口校验记录(Phase 2 产出):
110
+ ✅ isHardwareDecodingSupported(): bool — 规格匹配
111
+ ✅ initialize(): Future<void> — 规格匹配
112
+ ⚠️ setSpeed(rate): void — 规格为 setSpeed(double speed),以源码为准
113
+ ```
114
+
115
+ ---
116
+
117
+ ## 7. 边界情况处理
118
+
119
+ | 边界情况 | 处理规则 |
120
+ |----------|----------|
121
+ | 同一接口出现在多个 Demo | 各页面独立调用,允许重复(Demo 之间互不依赖) |
122
+ | Demo 无对应接口(纯 UI 演示) | 生成静态展示页面,文件头注明"本 Demo 无接口调用" |
123
+ | 接口含可选参数 | 生成默认参数调用 + 行内注释说明 |
124
+ | 步骤依赖前序步骤 | 页面内状态机控制按钮可用性(见第 5 节) |
125
+ | 接口返回复杂对象(Map/List) | 结果区用 `JsonEncoder.withIndent(' ')` 格式化后 `SelectableText` 展示 |
126
+ | 描述文档表格缺列(如无预期结果) | 对应字段以"以实际运行为准"占位,不阻塞生成 |