yidaconnector 2026.6.11

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 (79) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +383 -0
  3. package/bin/yida.js +670 -0
  4. package/lib/app/form-navigation.js +58 -0
  5. package/lib/app/get-schema.js +538 -0
  6. package/lib/auth/auth.js +294 -0
  7. package/lib/auth/cdp-browser-login.js +390 -0
  8. package/lib/auth/codex-login.js +71 -0
  9. package/lib/auth/login.js +475 -0
  10. package/lib/auth/org.js +363 -0
  11. package/lib/auth/qr-login.js +1563 -0
  12. package/lib/core/chalk.js +384 -0
  13. package/lib/core/check-update.js +82 -0
  14. package/lib/core/cli-error.js +39 -0
  15. package/lib/core/command-manifest.js +106 -0
  16. package/lib/core/env-cmd.js +545 -0
  17. package/lib/core/env-manager.js +601 -0
  18. package/lib/core/env.js +287 -0
  19. package/lib/core/i18n.js +177 -0
  20. package/lib/core/locales/ar.js +805 -0
  21. package/lib/core/locales/de.js +805 -0
  22. package/lib/core/locales/en.js +1623 -0
  23. package/lib/core/locales/es.js +805 -0
  24. package/lib/core/locales/fr.js +805 -0
  25. package/lib/core/locales/hi.js +805 -0
  26. package/lib/core/locales/ja.js +1197 -0
  27. package/lib/core/locales/ko.js +807 -0
  28. package/lib/core/locales/pt.js +805 -0
  29. package/lib/core/locales/vi.js +805 -0
  30. package/lib/core/locales/zh-HK.js +1233 -0
  31. package/lib/core/locales/zh.js +1584 -0
  32. package/lib/core/query-data.js +781 -0
  33. package/lib/core/redact.js +100 -0
  34. package/lib/core/utils.js +799 -0
  35. package/lib/core/yida-client.js +117 -0
  36. package/package.json +94 -0
  37. package/project/config.json +4 -0
  38. package/project/pages/src/demo-birthday-game.oyd.jsx +832 -0
  39. package/project/pages/src/demo-chip-insight.oyd.jsx +983 -0
  40. package/project/pages/src/demo-compat-smoke.oyd.jsx +58 -0
  41. package/project/pages/src/demo-crm-batch-entry.oyd.jsx +805 -0
  42. package/project/pages/src/demo-crm-dashboard.oyd.jsx +677 -0
  43. package/project/pages/src/demo-future-vision-2026.oyd.jsx +1102 -0
  44. package/project/pages/src/demo-ppt.oyd.jsx +1192 -0
  45. package/project/pages/src/demo-salary-calculator.oyd.jsx +904 -0
  46. package/project/pages/src/yidaconnector-knowledge-doc.oyd.jsx +1714 -0
  47. package/project/prd/demo-birthday-game.md +39 -0
  48. package/project/prd/demo-crm.md +463 -0
  49. package/project/prd/demo-dingtalk-ai-solution-center.md +425 -0
  50. package/project/prd/demo-future-vision-2026.md +78 -0
  51. package/project/prd/demo-salary-calculator.md +101 -0
  52. package/scripts/build-skills-package.js +406 -0
  53. package/scripts/check-syntax.js +59 -0
  54. package/scripts/demo-dws.sh +106 -0
  55. package/scripts/e2e-real/cleanup.js +67 -0
  56. package/scripts/e2e-real/fixtures/form-fields.json +18 -0
  57. package/scripts/e2e-real/full-runner.js +1566 -0
  58. package/scripts/e2e-real/runner.js +293 -0
  59. package/scripts/e2e-real/skill-coverage.js +115 -0
  60. package/scripts/generate-command-docs.js +109 -0
  61. package/scripts/nightly-smoke.js +134 -0
  62. package/scripts/postinstall.js +545 -0
  63. package/scripts/solution-center-runner.js +368 -0
  64. package/scripts/validate-ci.sh +50 -0
  65. package/scripts/validate-command-manifest.js +119 -0
  66. package/scripts/validate-package-size.js +78 -0
  67. package/scripts/validate-skills.js +247 -0
  68. package/scripts/validate-structure.js +66 -0
  69. package/yida-skills/SKILL.md +163 -0
  70. package/yida-skills/references/yida-api.md +1309 -0
  71. package/yida-skills/skills/large-file-write/SKILL.md +91 -0
  72. package/yida-skills/skills/large-file-write/references/write-patterns.md +149 -0
  73. package/yida-skills/skills/large-file-write/scripts/write.js +157 -0
  74. package/yida-skills/skills/yida-data-management/SKILL.md +252 -0
  75. package/yida-skills/skills/yida-data-management/references/api-matrix.md +49 -0
  76. package/yida-skills/skills/yida-data-management/references/data-format-guide.md +159 -0
  77. package/yida-skills/skills/yida-data-management/references/verified-endpoints.md +62 -0
  78. package/yida-skills/skills/yida-login/SKILL.md +159 -0
  79. package/yida-skills/skills/yida-logout/SKILL.md +67 -0
@@ -0,0 +1,91 @@
1
+ ---
2
+ name: large-file-write
3
+ description: 解决 heredoc 或 shell 命令写入大文件内容被截断的问题。当需要可靠地写入超过 100 行的大块内容时使用,通过 Node.js 脚本将内容作为模板字符串写入,绕过 shell 截断限制。不适用于:文件内容少于 100 行(直接使用 create_file 工具),或二进制文件写入。
4
+ ---
5
+
6
+ # Large File Write Skill
7
+
8
+ ## 问题背景
9
+
10
+ 在 AI Agent 模式下,使用 heredoc(`<< 'EOF'`)或 shell 命令向文件写入大块内容时,经常出现:
11
+ - 内容被截断(工具输出超过 token 限制)
12
+ - heredoc 内容未生效(zsh 特殊字符转义问题)
13
+ - 多次追加导致重复内容或语法错误
14
+ - Windows PowerShell 为了转义内容而执行 `Get-Content -Raw | ConvertTo-Json`,会把大 JSX/JS 文件整体读入内存并 JSON 转义,可能导致内存暴涨
15
+
16
+ ## 解决方案
17
+
18
+ 使用 Node.js 脚本 `scripts/write.js`,将内容作为 JS 字符串变量传入,绕过 shell 截断限制。
19
+
20
+ ## 使用方式
21
+
22
+ 三种写入模式的完整代码示例,详见 [references/write-patterns.md](./references/write-patterns.md):
23
+
24
+ - **模式一**:创建内容脚本后执行(推荐)— 用 `create_file` 创建临时 JS 脚本,再 `node` 执行
25
+ - **模式二**:追加内容到已有文件 — 用 `fs.appendFileSync` 追加大块内容
26
+ - **模式三**:使用通用写入脚本(stdin 模式)— 通过管道传入内容
27
+
28
+ ### 快速示例
29
+
30
+ ```js
31
+ // /tmp/content-payload.js
32
+ const fs = require('fs');
33
+ const content = `// 你的大块内容(支持任意长度)
34
+ export function myFunction() { ... }
35
+ `;
36
+ fs.writeFileSync('/path/to/target.js', content, 'utf8');
37
+ console.log('写入完成,行数:', content.split('\n').length);
38
+ ```
39
+
40
+ ```bash
41
+ node /tmp/content-payload.js
42
+ wc -l /path/to/target.js # 验证行数
43
+ ```
44
+
45
+ ## 核心原则
46
+
47
+ 1. **永远不要用 heredoc 写大文件** — 改用 `create_file` 工具创建临时 JS 脚本
48
+ 2. **永远不要用 PowerShell JSON 化大文件** — 禁止 `Get-Content -Raw <file> | ConvertTo-Json`、`ConvertFrom-Json` 处理 `.oyd.jsx/.jsx/.js` 页面源码
49
+ 3. **内容放在 JS 模板字符串里** — 支持任意长度,不受 shell 限制
50
+ 4. **写完立即验证** — `wc -l` 检查行数,`tail` 检查末尾内容
51
+ 5. **分段写入大文件** — 超过 300 行的内容,拆分为多个 `create_file` + `node` 执行
52
+ 6. **本技能不读写 memory**:文件写入为纯本地操作,不依赖跨会话的 memory 状态
53
+
54
+ ## 适用场景
55
+
56
+ - 宜搭自定义页面代码(通常 500-1500 行)
57
+ - Three.js 场景代码
58
+ - 任何超过 100 行的代码文件写入
59
+ - Windows 环境下写入/修补大 `.oyd.jsx` 页面源码
60
+
61
+ ## Windows / PowerShell 禁止模式
62
+
63
+ 不要为了转义或生成 patch,把大页面源码转换成 JSON 字符串:
64
+
65
+ ```powershell
66
+ # 禁止:会整体读入并生成多份转义副本,可能瞬间占用几十 GB 内存
67
+ Get-Content -Raw project\pages\src\vendor-section.oyd.jsx | ConvertTo-Json
68
+ ```
69
+
70
+ 正确做法是直接用 Node 写入目标文件;需要局部替换时,用 Node 读取后做精确字符串/AST 替换并直接 `fs.writeFileSync` 写回,不要额外包成 JSON patch。
71
+
72
+ ## 触发条件
73
+
74
+ **正向触发**:
75
+ - 需要写入超过 100 行的代码文件
76
+ - 使用 heredoc 或 shell 命令写文件时出现内容截断
77
+ - 写入宜搭自定义页面代码(通常 500-1500 行)
78
+
79
+ **不适用场景(不要触发)**:
80
+ - 文件内容少于 100 行 → 直接使用 `create_file` 工具
81
+ - 二进制文件写入 → 不适用
82
+ - 仅追加少量内容 → 直接使用 `create_file`
83
+
84
+ ## 异常处理
85
+
86
+ | 问题 | 原因 | 处理方式 |
87
+ |------|------|----------|
88
+ | `node: command not found` | Node.js 未安装 | 先安装 Node.js ≥ 16 |
89
+ | 脚本执行后文件为空 | 模板字符串语法错误 | 检查反引号是否闭合,特殊字符是否转义 |
90
+ | 写入不完整 | 内容超过单次 create_file 限制 | 按「分段写入」方式拆分为多个脚本 |
91
+ | 权限拒绝 | 目标路径无写权限 | 检查目录权限,或改用 `/tmp/` 路径 |
@@ -0,0 +1,149 @@
1
+ # 大文件写入模式参考
2
+
3
+ 本文档提供三种大文件写入模式的完整代码示例,供 AI Agent 直接参考使用。
4
+
5
+ ## 模式一:创建内容脚本后执行(推荐)
6
+
7
+ 适用于一次性写入大块内容(>100 行)。
8
+
9
+ ### Step 1:用 `create_file` 工具创建临时内容脚本
10
+
11
+ ```js
12
+ // /tmp/content-payload.js
13
+ const fs = require('fs');
14
+ const content = `
15
+ // 这里放你要写入的大块内容
16
+ // 支持任意长度,不受 heredoc 限制
17
+ export function myFunction() {
18
+ // ...
19
+ }
20
+ `;
21
+ fs.writeFileSync('/path/to/target.js', content, 'utf8');
22
+ console.log('写入完成,行数:', content.split('\n').length);
23
+ ```
24
+
25
+ ### Step 2:执行脚本
26
+
27
+ ```bash
28
+ node /tmp/content-payload.js
29
+ ```
30
+
31
+ ### Step 3:验证写入结果
32
+
33
+ ```bash
34
+ wc -l /path/to/target.js
35
+ tail -5 /path/to/target.js
36
+ ```
37
+
38
+ ---
39
+
40
+ ## 模式二:追加内容到已有文件
41
+
42
+ 适用于向已有文件末尾追加大块内容。
43
+
44
+ ```js
45
+ // /tmp/append-payload.js
46
+ const fs = require('fs');
47
+ const appendContent = `
48
+ // 追加的内容
49
+ export function additionalFunction() {
50
+ // ...
51
+ }
52
+ `;
53
+ fs.appendFileSync('/path/to/target.js', appendContent, 'utf8');
54
+ console.log('追加完成');
55
+ ```
56
+
57
+ 执行:
58
+
59
+ ```bash
60
+ node /tmp/append-payload.js
61
+ ```
62
+
63
+ ---
64
+
65
+ ## 模式三:使用通用写入脚本(stdin 模式)
66
+
67
+ 适用于通过管道传入内容的场景。
68
+
69
+ ```bash
70
+ node ~/.agents/skills/large-file-write/scripts/write.js \
71
+ --file /path/to/target.js \
72
+ --mode write # 或 append
73
+ ```
74
+
75
+ 然后通过 stdin 输入内容(Ctrl+D 结束)。
76
+
77
+ ---
78
+
79
+ ## Windows / PowerShell 禁止模式
80
+
81
+ **不要**用 PowerShell 把大 JSX/JS 文件转成 JSON patch:
82
+
83
+ ```powershell
84
+ # 禁止:会把整个文件读入内存并生成转义后的大字符串
85
+ Get-Content -Raw project\pages\src\vendor-section.oyd.jsx | ConvertTo-Json > vendor-patch.json
86
+ ```
87
+
88
+ 这种写法会同时持有原始源码、JSON 转义字符串、管道对象和输出缓冲。对包含 vendor、base64、压缩代码的 `.oyd.jsx` 文件,内存可能被放大到数十 GB。
89
+
90
+ 请改用 Node:
91
+
92
+ ```js
93
+ const fs = require('fs');
94
+ const target = 'project/pages/src/vendor-section.oyd.jsx';
95
+ const source = fs.readFileSync(target, 'utf8');
96
+ const next = source.replace('old snippet', 'new snippet');
97
+ fs.writeFileSync(target, next, 'utf8');
98
+ ```
99
+
100
+ 如果替换内容很大,按下文“分段写入大文件”拆分。
101
+
102
+ ---
103
+
104
+ ## 分段写入大文件(>300 行)
105
+
106
+ 当单次内容超过 300 行时,拆分为多个脚本分段写入:
107
+
108
+ ```js
109
+ // /tmp/part1-payload.js — 写入第一段(文件头 + 前半部分)
110
+ const fs = require('fs');
111
+ const part1 = `
112
+ // === 第一段内容 ===
113
+ const CONSTANTS = { ... };
114
+ export function functionA() { ... }
115
+ `;
116
+ fs.writeFileSync('/path/to/target.js', part1, 'utf8');
117
+ console.log('第一段写入完成');
118
+ ```
119
+
120
+ ```js
121
+ // /tmp/part2-payload.js — 追加第二段
122
+ const fs = require('fs');
123
+ const part2 = `
124
+ // === 第二段内容 ===
125
+ export function functionB() { ... }
126
+ export function functionC() { ... }
127
+ `;
128
+ fs.appendFileSync('/path/to/target.js', part2, 'utf8');
129
+ console.log('第二段追加完成');
130
+ ```
131
+
132
+ 验证最终结果:
133
+
134
+ ```bash
135
+ wc -l /path/to/target.js
136
+ head -5 /path/to/target.js
137
+ tail -5 /path/to/target.js
138
+ ```
139
+
140
+ ---
141
+
142
+ ## 常见错误与修复
143
+
144
+ | 错误现象 | 原因 | 修复方式 |
145
+ |---------|------|---------|
146
+ | 文件为空 | 模板字符串反引号未闭合 | 检查 `` ` `` 是否成对,特殊字符是否转义 |
147
+ | 内容截断 | 单次 create_file 超过 token 限制 | 拆分为多个脚本分段写入 |
148
+ | 权限拒绝 | 目标路径无写权限 | 改用 `/tmp/` 路径,或检查目录权限 |
149
+ | node 命令未找到 | Node.js 未安装 | 先安装 Node.js ≥ 16 |
@@ -0,0 +1,157 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * large-file-write - Node.js 大文件可靠写入工具
4
+ *
5
+ * 解决 AI Agent 模式下 heredoc / shell 命令写入大文件时内容被截断的问题。
6
+ *
7
+ * 用法:
8
+ * node write.js --file <目标文件路径> [--mode write|append] [--encoding utf8]
9
+ *
10
+ * 内容来源(三选一):
11
+ * 1. stdin:echo "content" | node write.js --file out.js
12
+ * 2. --content-file <临时内容文件>:node write.js --file out.js --content-file /tmp/content.txt
13
+ * 3. --payload <JS文件>:node write.js --payload /tmp/payload.js(payload 文件自行调用 fs 写入)
14
+ */
15
+
16
+ const fs = require('fs');
17
+ const path = require('path');
18
+ const readline = require('readline');
19
+
20
+ // ─── 解析命令行参数 ───────────────────────────────────────────────────────────
21
+
22
+ function parseArgs(argv) {
23
+ const args = {};
24
+ for (let i = 2; i < argv.length; i++) {
25
+ const key = argv[i];
26
+ if (key.startsWith('--')) {
27
+ const name = key.slice(2);
28
+ const value = argv[i + 1] && !argv[i + 1].startsWith('--') ? argv[++i] : true;
29
+ args[name] = value;
30
+ }
31
+ }
32
+ return args;
33
+ }
34
+
35
+ const args = parseArgs(process.argv);
36
+
37
+ // ─── 帮助信息 ─────────────────────────────────────────────────────────────────
38
+
39
+ if (args.help || args.h) {
40
+ console.log(`
41
+ large-file-write - 大文件可靠写入工具
42
+
43
+ 用法:
44
+ node write.js --file <目标路径> [选项]
45
+
46
+ 选项:
47
+ --file <path> 目标文件路径(必填,除非使用 --payload)
48
+ --mode <write|append> 写入模式,默认 write(覆盖)
49
+ --encoding <enc> 文件编码,默认 utf8
50
+ --content-file <path> 从指定文件读取内容后写入目标文件
51
+ --payload <path> 执行一个自包含的 JS 脚本(脚本内自行调用 fs 写入)
52
+ --verify 写入后输出行数和末尾5行进行验证
53
+ --help 显示帮助
54
+
55
+ 示例:
56
+ # 从 stdin 写入
57
+ echo "hello world" | node write.js --file /tmp/out.txt
58
+
59
+ # 从内容文件写入
60
+ node write.js --file /tmp/out.js --content-file /tmp/content.txt --verify
61
+
62
+ # 执行自包含 payload 脚本
63
+ node write.js --payload /tmp/my-payload.js
64
+ `);
65
+ process.exit(0);
66
+ }
67
+
68
+ // ─── 执行 payload 模式 ────────────────────────────────────────────────────────
69
+
70
+ if (args.payload) {
71
+ const payloadPath = path.resolve(args.payload);
72
+ if (!fs.existsSync(payloadPath)) {
73
+ console.error(`❌ payload 文件不存在:${payloadPath}`);
74
+ process.exit(1);
75
+ }
76
+ console.log(`▶ 执行 payload:${payloadPath}`);
77
+ require(payloadPath);
78
+ process.exit(0);
79
+ }
80
+
81
+ // ─── 普通写入模式 ─────────────────────────────────────────────────────────────
82
+
83
+ if (!args.file) {
84
+ console.error('❌ 缺少必填参数 --file <目标文件路径>');
85
+ console.error(' 运行 node write.js --help 查看帮助');
86
+ process.exit(1);
87
+ }
88
+
89
+ const targetFile = path.resolve(args.file);
90
+ const writeMode = args.mode === 'append' ? 'a' : 'w';
91
+ const encoding = args.encoding || 'utf8';
92
+ const shouldVerify = args.verify === true || args.verify === 'true';
93
+
94
+ // 确保目标目录存在
95
+ const targetDir = path.dirname(targetFile);
96
+ if (!fs.existsSync(targetDir)) {
97
+ fs.mkdirSync(targetDir, { recursive: true });
98
+ console.log(`📁 已创建目录:${targetDir}`);
99
+ }
100
+
101
+ function writeContent(content) {
102
+ const flag = writeMode;
103
+ fs.writeFileSync(targetFile, content, { encoding, flag });
104
+
105
+ const totalLines = content.split('\n').length;
106
+ const actualLines = fs.readFileSync(targetFile, 'utf8').split('\n').length;
107
+ const modeLabel = flag === 'a' ? '追加' : '写入';
108
+
109
+ console.log(`✅ ${modeLabel}成功:${targetFile}`);
110
+ console.log(` 本次内容:${totalLines} 行 | 文件总行数:${actualLines} 行`);
111
+
112
+ if (shouldVerify) {
113
+ const lines = fs.readFileSync(targetFile, 'utf8').split('\n');
114
+ const tail = lines.slice(-5).join('\n');
115
+ console.log('\n📋 文件末尾 5 行:');
116
+ console.log('─'.repeat(50));
117
+ console.log(tail);
118
+ console.log('─'.repeat(50));
119
+ }
120
+ }
121
+
122
+ // ─── 从 --content-file 读取内容 ───────────────────────────────────────────────
123
+
124
+ if (args['content-file']) {
125
+ const contentFilePath = path.resolve(args['content-file']);
126
+ if (!fs.existsSync(contentFilePath)) {
127
+ console.error(`❌ 内容文件不存在:${contentFilePath}`);
128
+ process.exit(1);
129
+ }
130
+ const content = fs.readFileSync(contentFilePath, encoding);
131
+ writeContent(content);
132
+ process.exit(0);
133
+ }
134
+
135
+ // ─── 从 stdin 读取内容 ────────────────────────────────────────────────────────
136
+
137
+ const isTTY = process.stdin.isTTY;
138
+
139
+ if (isTTY) {
140
+ console.log('📝 请输入内容(输入完成后按 Ctrl+D 结束):');
141
+ }
142
+
143
+ const chunks = [];
144
+ const rl = readline.createInterface({ input: process.stdin, crlfDelay: Infinity });
145
+
146
+ rl.on('line', (line) => {
147
+ chunks.push(line);
148
+ });
149
+
150
+ rl.on('close', () => {
151
+ const content = chunks.join('\n');
152
+ if (!content.trim()) {
153
+ console.error('❌ 未接收到任何内容,请通过 stdin 或 --content-file 提供内容');
154
+ process.exit(1);
155
+ }
156
+ writeContent(content);
157
+ });
@@ -0,0 +1,252 @@
1
+ ---
2
+ name: yida-data-management
3
+ description: 宜搭数据管理。表单实例/子表/流程实例/任务中心的查询、新增、更新。表单走 /v1/form/,流程走 /v1/process/,不能混用。
4
+ ---
5
+
6
+ # 数据管理
7
+
8
+ ## 严格禁止 (NEVER DO)
9
+
10
+ - 不要混用表单接口和流程接口,两套接口完全独立,参数和返回结构不同
11
+ - 不要编造 formInstId 或 processInstanceId,必须从查询结果中提取
12
+ - 不要用此命令修改表单结构(字段增删改),应使用 `yida-create-form-page`
13
+ - **绝对禁止猜测或编造字段 ID(fieldId)**,宜搭字段 ID 由平台随机生成(如 `textField_eftt1aa5m`),无法预测,必须通过 `yidaconnector get-schema` 获取
14
+
15
+ ## 严格要求 (MUST DO)
16
+
17
+ - 操作前先用 query 命令确认目标数据存在
18
+ - 批量操作单次不超过 30 条记录
19
+ - 删除数据前必须向用户展示操作摘要并获得明确确认
20
+ - **录入/更新数据前,必须先执行 `yidaconnector get-schema` 获取真实字段 ID,并将字段 ID 映射记录到 `.cache/<项目名>-schema.json`**
21
+ - **生成测试数据或录入/更新数据时,`DateField` / `CascadeDateField` 必须使用 13 位毫秒时间戳(如 `1719705600000`),不要传 `YYYY-MM-DD`、`YYYY-MM-DD HH:mm:ss` 或 ISO 字符串**
22
+ - **录入数据后,必须执行 `yidaconnector data query` 抽查至少 1 条记录,确认 `formData` 中字段有实际值(非空),否则说明字段 ID 有误,需重新排查**
23
+ - **读取子表明细超过 50 行时,必须使用 `yidaconnector data query subform` 或 `listTableDataByFormInstIdAndTableId` 分页查询完整子表;不要把 `searchFormDatas.currentPage` 当作子表分页**
24
+ - **本技能不读写 memory**:数据操作通过 CLI 命令写入宜搭平台,不依赖跨会话的 memory 状态
25
+ - 一次性造数、旧数据修正、字段迁移脚本可以使用 Python 或 JS,优先选择更快更清晰的实现;脚本、导入数据、查询条件文件必须放在 `.cache/yidaconnector/` 下,并复用真实查询到的 appType/formUuid/fieldId/formInstId
26
+ - **禁止在仓库根目录生成导入用的 `*.json`、`*.js`、`*.py`、`*.csv` 临时文件**;推荐使用 `.cache/yidaconnector/data-import/` 存放数据文件,`.cache/yidaconnector/scripts/` 存放一次性执行脚本
27
+
28
+ ## 适用场景
29
+
30
+ 用户需要"查询数据"、"新增记录"、"更新数据"、"查看表单实例"、"发起流程"时使用。
31
+
32
+ **关键区分**:
33
+ - 操作表单数据记录(增删改查)→ 本技能
34
+ - 修改表单结构(字段增删改)→ `yida-create-form-page`
35
+ - 自定义页面调用连接器或外部 API 数据源 → `yida-data-source-connectors`
36
+ - 表单接口(`/v1/form/`)vs 流程接口(`/v1/process/`)不能混用
37
+
38
+ ## 触发条件
39
+
40
+ **正向触发**:
41
+ - "查询数据"、"新增记录"、"更新数据"
42
+ - "查看表单实例"、"发起流程"
43
+ - "录入数据"、"批量导入"、"查询待办任务"
44
+
45
+ **不适用场景(不要触发)**:
46
+ - 修改表单结构(字段增删改)→ `yida-create-form-page`
47
+ - 配置集成自动化 → `yida-integration`
48
+ - 自定义页面接入 HTTP 连接器、第三方接口或外部系统数据 → `yida-data-source-connectors`
49
+ - 获取字段 ID → `yida-get-schema`
50
+ - 表单接口(`/v1/form/`)和流程接口(`/v1/process/`)不能混用
51
+
52
+ ## 危险操作确认
53
+
54
+ 删除数据记录为不可逆操作,执行前必须:
55
+ 1. 展示将删除的记录摘要(数量 + 关键字段)
56
+ 2. 等待用户明确确认
57
+ 3. 执行删除
58
+
59
+ ---
60
+
61
+
62
+ > 表单与流程是两套独立接口,主键、参数、返回结构都不同,不能混用。
63
+
64
+ ## 命令
65
+
66
+ ### 表单实例
67
+
68
+ ```bash
69
+ yidaconnector data query form <appType> <formUuid> [--page 1 --size 20] [--search-json '<json>'|--search-file .cache/yidaconnector/data-import/search.json] [--resolve-aliases]
70
+ yidaconnector data get form <appType> --inst-id <formInstId>
71
+ yidaconnector data create form <appType> <formUuid> --data-json '<json>' [--resolve-aliases]
72
+ yidaconnector data create form <appType> <formUuid> --data-file .cache/yidaconnector/data-import/record.json [--resolve-aliases]
73
+ yidaconnector data update form <appType> --inst-id <formInstId> --form-uuid <formUuid> --data-json '<json>' [--resolve-aliases]
74
+ yidaconnector data update form <appType> --inst-id <formInstId> --form-uuid <formUuid> --data-file .cache/yidaconnector/data-import/patch.json [--resolve-aliases]
75
+ yidaconnector data query subform <appType> <formUuid> --inst-id <formInstId> --table-field-id <fieldId|alias> [--page 1 --size 100] [--resolve-aliases]
76
+ ```
77
+
78
+ 当 JSON 使用宜搭组件别名作为 key 时,追加 `--resolve-aliases`,YidaConnector 会先读取表单 Schema 中的 `componentAlias.items`,再将别名转换为真实 `fieldId` 后调用数据接口。更新类命令若要解析别名,必须额外传 `--form-uuid <formUuid>`。
79
+
80
+ ### 子表超过 50 行
81
+
82
+ 当 `searchFormDatas` 或 `getFormDataById` 返回的 `formData.tableField_xxx` 刚好是 50 行时,优先判断为详情接口对子表内嵌数据做了截断,不要直接下结论为"没有更多数据"。
83
+
84
+ 正确处理流程:
85
+
86
+ 1. 先确认主记录的 `formInstId` 和子表真实 `tableFieldId`;如果只有别名,先执行 `yidaconnector get-schema` 或给 `query subform` 追加 `--resolve-aliases`。
87
+ 2. 使用 `yidaconnector data query subform <appType> <formUuid> --inst-id <formInstId> --table-field-id <tableFieldId> --page 1 --size 100` 查询子表第一页。
88
+ 3. 如果返回 `totalCount` 大于 `data.length`,继续按 `currentPage/pageSize` 翻页,或在脚本中复用 `listTableDataByFormInstIdAndTableId` 拉全量。
89
+ 4. 不要通过 DOM、虚拟滚动列表、页面全局变量抓取子表全量数据;这类方式依赖页面实现,不能作为稳定数据管理方案。
90
+
91
+ 注意:`searchFormDatas.currentPage` 分页的是主表实例列表,不是某条实例里的子表行。把 `currentPage` 改为 2 后返回空,只能说明主表第二页没有记录,不能证明子表不支持分页。
92
+
93
+ 不要把"创建自定义数据源"作为解决宜搭表单/子表 50 行截断的首选方案;只有在确实需要调用 HTTP 连接器、第三方接口或外部系统数据时,才切换到 `yida-data-source-connectors`。
94
+
95
+ ### 流程实例
96
+
97
+ ```bash
98
+ yidaconnector data query process <appType> <formUuid> [--instance-status RUNNING] [--search-file .cache/yidaconnector/data-import/process-search.json] [--resolve-aliases]
99
+ yidaconnector data get process <appType> --process-inst-id <processInstanceId>
100
+ yidaconnector data create process <appType> <formUuid> --process-code <processCode> --data-json '<json>' [--resolve-aliases]
101
+ yidaconnector data create process <appType> <formUuid> --process-code <processCode> --data-file .cache/yidaconnector/data-import/process-record.json [--resolve-aliases]
102
+ yidaconnector data update process <appType> --process-inst-id <processInstanceId> --form-uuid <formUuid> --data-json '<json>' [--resolve-aliases]
103
+ yidaconnector data update process <appType> --process-inst-id <processInstanceId> --form-uuid <formUuid> --data-file .cache/yidaconnector/data-import/process-patch.json [--resolve-aliases]
104
+ yidaconnector data query operation-records <appType> --process-inst-id <processInstanceId>
105
+ yidaconnector data execute task <appType> --task-id <taskId> --process-inst-id <processInstanceId> --out-result AGREE --remark '同意' [--data-file .cache/yidaconnector/data-import/task-data.json] [--form-uuid <formUuid>] [--resolve-aliases]
106
+ ```
107
+
108
+ ### 任务中心
109
+
110
+ ```bash
111
+ yidaconnector data query tasks <appType> --type todo|done|submitted|cc [--page 1 --size 20]
112
+ ```
113
+
114
+ ## 接口总览
115
+
116
+ ### 表单实例
117
+
118
+ | 接口 | 方法 | 说明 |
119
+ |------|------|------|
120
+ | `searchFormDatas` | GET | 查询列表 |
121
+ | `searchFormDataIds` | GET | 查询 ID 列表 |
122
+ | `getFormDataById` | GET | 查询详情 |
123
+ | `saveFormData` | POST | 新增 |
124
+ | `updateFormData` | POST | 更新 |
125
+ | `listTableDataByFormInstIdAndTableId` | GET | 查询子表数据 |
126
+
127
+ ### 流程实例
128
+
129
+ | 接口 | 方法 | 说明 |
130
+ |------|------|------|
131
+ | `startProcessInstance` | POST | 发起流程 |
132
+ | `getInstanceIds` | GET | 查询 ID 列表 |
133
+ | `getInstances` | GET | 查询列表 |
134
+ | `getInstanceById` | GET | 查询详情 |
135
+ | `updateInstance` | POST | 更新 |
136
+ | `getOperationRecords` | GET | 审批记录 |
137
+ | `executeTask` | POST | 执行任务 |
138
+
139
+ ### 任务中心
140
+
141
+ | 接口 | 说明 |
142
+ |------|------|
143
+ | `getTodoTasksInApp` | 待办 |
144
+ | `getDoneTasksInApp` | 已完成 |
145
+ | `getMySubmitInApp` | 已提交 |
146
+ | `getNotifyMeTasksInApp` | 抄送 |
147
+
148
+ ## 数据格式
149
+
150
+ ### 查询条件 `searchFieldJson`
151
+
152
+ 必须传**字符串**:
153
+
154
+ ```json
155
+ [{"key":"textField_xxx","value":"测试","type":"TEXT","operator":"eq","componentName":"TextField"}]
156
+ ```
157
+
158
+ ### 保存/更新数据
159
+
160
+ ```json
161
+ {"textField_xxx":"文本","numberField_xxx":10,"dateField_xxx":1719705600000,"employeeField_xxx":["userId"]}
162
+ ```
163
+
164
+ 当 JSON 较长或用于批量导入时,写入 `.cache/yidaconnector/data-import/<name>.json`,再使用 `--data-file` 或 `--search-file`;不要为了拼接命令在仓库根目录生成临时脚本。
165
+
166
+ ### 常见字段格式
167
+
168
+ | 组件类型 | 查询格式 | 保存格式 |
169
+ |---------|---------|----------|
170
+ | 文本 | `"文本"` | `"文本"` |
171
+ | 数字 | `["1","10"]` 或单值 | `1` |
172
+ | 单选 | `"选项一"` | `"选项一"` |
173
+ | 多选 | `["选项一"]` | `["选项一","选项二"]` |
174
+ | 日期 | `[开始毫秒时间戳,结束毫秒时间戳]` | `13 位毫秒时间戳` |
175
+ | 成员 | `["userId"]` | `["userId"]` |
176
+ | 部门 | `["deptId"]` | `["deptId"]` |
177
+ | 子表 | `"模糊搜索"` | `[{"textField_xxx":"值"}]` |
178
+ | 关联表单 | 不支持直接查询 | `[{"appType":"xxx","formUuid":"xxx","instanceId":"xxx"}]` |
179
+
180
+ ### 日期字段写入约定
181
+
182
+ - `DateField` 保存/更新值必须是 13 位毫秒时间戳,例如 `1719705600000`。
183
+ - `CascadeDateField` 保存/更新值必须是毫秒时间戳数组,例如 `[1719705600000,1722384000000]`。
184
+ - 生成测试数据时,先用 `new Date('2024-06-30T00:00:00+08:00').getTime()` 或等价方式转换,不要直接写 `"2024-06-30"`。
185
+ - 日期字符串可能导致保存失败、字段为空,或后续报表/筛选异常。
186
+
187
+ ```bash
188
+ yidaconnector data create form APP_xxx FORM-xxx --data-json '{
189
+ "textField_xxx": "测试记录",
190
+ "dateField_xxx": 1719705600000,
191
+ "cascadeDateField_xxx": [1719705600000,1722384000000]
192
+ }'
193
+ ```
194
+
195
+ ### 关联表单字段
196
+
197
+ 关联表单字段保存时必须使用数组对象格式,包含三个必填字段:
198
+
199
+ ```bash
200
+ # 示例:创建带关联客户的商机
201
+ yidaconnector data create form APP_xxx FORM-商机表 --data-json '{
202
+ "textField_xxx": "商机名称",
203
+ "associationFormField_xxx": [{"appType":"APP_xxx","formUuid":"FORM-客户表","instanceId":"FINST-xxx"}]
204
+ }'
205
+ ```
206
+
207
+ > 注意:字段名是 `instanceId`(不是 formInstId),三个字段缺一不可
208
+
209
+
210
+ ## 代码示例
211
+
212
+ > 需要参考表单字段定义和数据插入写法时,执行以下命令获取示例,再用 `read_file` 读取:
213
+
214
+ ```bash
215
+ yidaconnector sample yida-data-management form-field-template # 表单字段定义模板(字段类型/必填/选项配置)及数据插入示例
216
+ ```
217
+
218
+ ## 注意事项
219
+
220
+ - `pageSize` 最大 100,QPS 限制约 40 次/秒
221
+ - `searchFieldJson` 和 `dynamicOrder` 必须传字符串
222
+ - 字段 ID 通过 `yidaconnector get-schema` 获取,不要手写猜测
223
+ - 批量脚本可以用 Python `subprocess` 调用 `yidaconnector data ...`,也可以用 JS 复用 Node 工具;脚本必须放在 `.cache/yidaconnector/scripts/`,导入数据放在 `.cache/yidaconnector/data-import/`
224
+
225
+ ## 异常处理
226
+
227
+ | 异常场景 | 处理方式 |
228
+ |---------|----------|
229
+ | 查询返回空结果 | 确认 formUuid 正确,检查查询条件是否过于严格 |
230
+ | 子表只返回 50 行 | 不要翻 `searchFormDatas.currentPage`;使用 `query subform` / `listTableDataByFormInstIdAndTableId` 按 `formInstId + tableFieldId` 分页查询 |
231
+ | 新增数据后字段值为空 | 字段 ID 有误,先执行 `yidaconnector get-schema` 获取真实 fieldId |
232
+ | 更新失败(formInstId 不存在) | 先用 query 命令确认记录存在,不要猜测 formInstId |
233
+ | 接口返回 401/未登录 | 执行 `yidaconnector login` 重新登录 |
234
+ | QPS 超限(429) | 降低请求频率,批量操作单次不超过 30 条 |
235
+ | 删除操作误删 | 删除前必须展示操作摘要并获得用户明确确认,不可逆操作 |
236
+ | 流程接口用了表单接口路径 | 检查接口路径:表单用 `/v1/form/`,流程用 `/v1/process/` |
237
+
238
+ ## Agent 错误处理策略
239
+
240
+ 当 Agent 执行本技能遇到错误时,必须遵循以下默认行为:
241
+
242
+ | 错误类型 | 默认处理策略 |
243
+ |---------|-------------|
244
+ | 命令执行失败 | 停止执行,向用户展示错误信息,询问是否重试或调整参数 |
245
+ | 参数缺失(appType/formUuid/fieldId 等) | 主动询问用户补充,或引导用户使用 `yida-get-schema` 获取 |
246
+ | 权限不足 / 登录态失效 | 停止执行,提示用户执行 `yidaconnector login` 重新登录 |
247
+ | 字段 ID 无效 | 停止执行,引导用户执行 `yidaconnector get-schema` 获取真实字段 ID |
248
+ | 删除操作前 | 必须先展示操作摘要(数量 + 关键字段),等待用户明确确认 |
249
+ | QPS 超限 | 降低请求频率,单次批量操作不超过 30 条,间隔 1 秒重试 |
250
+ | 表单/流程接口混用 | 停止执行,提示用户检查接口类型(表单用 `/v1/form/`,流程用 `/v1/process/`) |
251
+ | 网络超时 | 重试 1 次,仍失败则停止并提示用户检查网络 |
252
+ | 未知错误 | 停止执行,完整展示错误信息,建议用户反馈问题 |