@xtalpi/agentic-lab-skills 0.0.9 → 0.0.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 (68) hide show
  1. package/README.md +1 -1
  2. package/package.json +14 -14
  3. package/skills/lab-flow-designer/SKILL.md +612 -593
  4. package/skills/lab-flow-designer/embedded-template/SKILL.md +103 -88
  5. package/skills/lab-flow-designer/embedded-template/pools//345/205/245/345/217/243/346/261/240.md +21 -12
  6. package/skills/lab-flow-designer/embedded-template/pools//345/207/272/345/217/243/346/261/240.md +21 -12
  7. package/skills/lab-flow-designer/embedded-template/scripts//347/244/272/344/276/213/346/225/260/346/215/256/344/270/216/346/240/241/351/252/214/351/227/250/346/216/247.js +142 -142
  8. package/skills/lab-flow-designer/embedded-template/valves//347/244/272/344/276/213/346/225/260/346/215/256/344/270/216/346/240/241/351/252/214/351/227/250/346/216/247.md +114 -99
  9. package/skills/lab-flow-designer/references/agentic-lab-processer.md +122 -78
  10. package/skills/lab-flow-designer/references/agentic-lab-sdk.md +534 -361
  11. package/skills/lab-flow-designer/references/rhea-api/README.md +7 -7
  12. package/skills/lab-flow-designer/references/rhea-api/execute_process_batch.md +58 -58
  13. package/skills/lab-flow-designer/references/skill-package-layout.md +268 -204
  14. package/skills/lab-flow-designer/references//344/270/232/345/212/241/346/265/201/347/250/213/346/226/207/346/241/243/346/240/207/345/207/206.md +216 -208
  15. package/skills/lab-flow-designer/templates//344/270/232/345/212/241/346/265/201/347/250/213/346/226/207/346/241/243/346/250/241/346/235/277.md +192 -169
  16. package/skills/lab-flow-designer/templates//344/270/232/345/212/241/346/265/201/347/250/213/346/226/207/346/241/243/347/244/272/344/276/213.md +207 -197
  17. package/skills/lab-flow-designer/testing/test-processer.mjs +1240 -1075
  18. package/skills/lab-nocobase-flow-generator/SKILL.md +164 -164
  19. package/skills/lab-nocobase-flow-generator/examples/setting/350/241/250/350/216/267/345/217/226/345/244/226/351/203/250/346/234/215/345/212/241.js +70 -70
  20. package/skills/lab-nocobase-flow-generator/examples//346/237/245/350/257/242/345/214/226/345/255/246/345/223/201/344/277/241/346/201/257.js +30 -30
  21. package/skills/lab-nocobase-flow-generator/references/doc-standard.md +84 -84
  22. package/skills/lab-nocobase-flow-generator/references/runtime-api.md +224 -224
  23. package/skills/lab-nocobase-flow-generator/templates//350/204/232/346/234/254/351/200/273/350/276/221/346/226/207/346/241/243/346/250/241/346/235/277.md +121 -121
  24. package/skills/lab-nocobase-flow-generator/templates//350/204/232/346/234/254/351/200/273/350/276/221/346/226/207/346/241/243/347/244/272/344/276/213.md +67 -67
  25. package/skills/lab-orbit-component-builder/SKILL.md +353 -353
  26. package/skills/lab-orbit-component-builder/examples/xnb-component-template/.env.local.example +27 -27
  27. package/skills/lab-orbit-component-builder/examples/xnb-component-template/.eslintignore +7 -7
  28. package/skills/lab-orbit-component-builder/examples/xnb-component-template/.eslintrc.cjs +88 -88
  29. package/skills/lab-orbit-component-builder/examples/xnb-component-template/.nvmrc +1 -1
  30. package/skills/lab-orbit-component-builder/examples/xnb-component-template/AgenticAppAPI.md +268 -268
  31. package/skills/lab-orbit-component-builder/examples/xnb-component-template/Jenkinsfile +106 -106
  32. package/skills/lab-orbit-component-builder/examples/xnb-component-template/OrbitAPI.md +453 -453
  33. package/skills/lab-orbit-component-builder/examples/xnb-component-template/README.md +176 -176
  34. package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/public/index.html +12 -12
  35. package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/App.vue +151 -151
  36. package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/components/DevOpenerLauncher.vue +143 -143
  37. package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/global.d.ts +77 -77
  38. package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/main.ts +308 -308
  39. package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/mockXNBBitable.ts +119 -119
  40. package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/shims-vue.d.ts +6 -6
  41. package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/utils/devOpenerHost.ts +75 -75
  42. package/skills/lab-orbit-component-builder/examples/xnb-component-template/index.html +13 -13
  43. package/skills/lab-orbit-component-builder/examples/xnb-component-template/package.json +60 -60
  44. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/api/agenticlabTickets.ts +110 -110
  45. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/entries/bitable.ts +4 -4
  46. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/entries/custom-page.ts +4 -4
  47. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/index.ts +1 -1
  48. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/styles/orbit-quasar-host.scss +19 -19
  49. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/types/context.ts +15 -15
  50. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/types/xnb-context.ts +70 -70
  51. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/use/useBitablePage.ts +189 -189
  52. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/use/useSuperCellDemo.ts +257 -257
  53. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/use/useSuperTableBitableLifecycle.ts +555 -555
  54. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/utils/openerInitParams.ts +158 -158
  55. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/utils/openerTicketIds.ts +32 -32
  56. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/utils/orbitHttpClient.ts +110 -110
  57. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/utils/request.ts +92 -92
  58. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/views/bitable.vue +67 -67
  59. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/views/custom-page.vue +140 -140
  60. package/skills/lab-orbit-component-builder/examples/xnb-component-template/tsconfig.json +45 -45
  61. package/skills/lab-orbit-component-builder/examples/xnb-component-template/vite.config.ts +170 -170
  62. package/skills/lab-orbit-component-builder/examples/xnb-component-template/vite.dev.config.ts +58 -58
  63. package/skills/lab-orbit-component-builder/references/flow-document-human-ui.md +65 -65
  64. package/skills/lab-orbit-component-builder/references/orbit-vue-conventions.md +133 -133
  65. package/skills/lab-orbit-component-builder/references/pool-schema-to-columns.md +67 -67
  66. package/skills/lab-orbit-component-builder/references/vue-template-checklist.md +179 -179
  67. package/skills/lab-orbit-component-builder/references/xnb-context-vue-props.md +49 -49
  68. package/skills/lab-orbit-component-builder/references/xnbitable-vue-parity.md +32 -32
@@ -1,593 +1,612 @@
1
- ---
2
- name: lab-flow-designer
3
- description: >-
4
- 根据流程说明 Markdown 初次生成流程注册包时,须先按 references/业务流程文档标准.md 做合规预检,不通过则不得写入产出包并须输出优化建议;对已存在的流程注册包做增量修改时跳过流程文档预检。
5
- 也可根据用户描述生成符合规范的业务流程文档模板,供用户完善后用于流程注册包生成。
6
- 产出与本 skill 内 embedded-template、references/skill-package-layout.md 版式同构;根 SKILL.md 须含概述、核心概念、流程图(Mermaid 池为矩形、门控为六边形)、连接关系、节点清单、门控执行规范、使用方式。
7
- Use when scaffolding flow skills, valve scripts from gate YAML and compound KB rules, Processer start/complete from pipeline docs, or generating flow document templates.
8
- license: Proprietary
9
- metadata:
10
- embedded-template-dir: embedded-template
11
- package-shape-ref: references/skill-package-layout.md
12
- ---
13
-
14
- # 从流程说明生成流程注册包
15
-
16
- ## 适用场景
17
-
18
- - 用户提供**流程说明 Markdown**的路径,并需要在工作区中生成与模板**同构**的流程注册包:根级 `SKILL.md`、`pools/*.md`、`valves/*.md`、`scripts/*.js`;或在**已有流程注册包目录**上修改、增补上述文件。
19
- - 用户希望生成一份**业务流程文档模板**,用于梳理和描述新的业务流程,完善后再用本技能生成流程注册包。
20
-
21
- ## 会话模式判定(须先执行)
22
-
23
- 根据用户意图选择模式;**不得**在「迭代修改」会话中强行要求流程文档预检。
24
-
25
- | 模式 | 判定要点(满足其一即可倾向该模式) | 流程文档合规预检 |
26
- |------|-----------------------------------|------------------|
27
- | **初次生成** | 从流程说明**新建**整包:用户给出(或隐含)流程说明 `.md` 路径,且目标为**新建或清空后写入**完整 `SKILL.md` + `pools/` + `valves/` + `scripts/`;或用户明确要求「按流程文档生成流程注册包」「脚手架」等。 | **必须**:先完成下文「流程文档合规预检」且**通过**后,才允许进入「生成流程」。 |
28
- | **迭代修改** | 在**已存在**的流程注册包根目录上工作:目录内已有符合布局的 `SKILL.md` 与 `pools/` / `valves/` / `scripts/`(或用户明确仅改其中部分文件);诉求为修脚本、改 Schema、改文案、对齐 agentic-lab-sdk、小范围结构调整等,**且**非「用一份流程说明从零重写全包」。 | **跳过**:不要求对照流程说明做合规预检;修改仍须遵守 [references/skill-package-layout.md](references/skill-package-layout.md)、[references/agentic-lab-sdk.md](references/agentic-lab-sdk.md) 等本 skill 内条文。 |
29
- | **生成流程文档** | 用户要求生成流程文档、流程模板、业务流程描述文档 | 基于模板和用户描述,生成预填充的业务流程文档并写入本地文件;**不生成**流程注册包。 |
30
-
31
- **模糊时**:若用户同时给出流程说明路径与已有包路径,且表述为「用新流程说明**整体替换**本包」,按 **初次生成** 处理(须预检新流程文档);若仅「在某某包上改一下门控脚本」,按 **迭代修改** 处理。
32
-
33
- ## 输入材料
34
-
35
- | 材料 | 说明 |
36
- |------|------|
37
- | 流程说明 | **仅「初次生成」模式**下必用:用户指定的 `.md` 文件;须先通过「流程文档合规预检」([references/业务流程文档标准.md](references/业务流程文档标准.md)),未通过不得进入「生成流程」。**「迭代修改」模式**可不引用流程说明文件 |
38
- | **极简目录范例(优先打开)** | 本 skill 内 [`embedded-template/`](embedded-template/):2 池 + 1 门控;[`embedded-template/valves/示例数据与校验门控.md`](embedded-template/valves/示例数据与校验门控.md) 与 [`embedded-template/scripts/示例数据与校验门控.js`](embedded-template/scripts/示例数据与校验门控.js) 含「数据查询 / 映射 / 规则」与 SDK 对齐的完整参考 |
39
- | **版式条文** | [references/skill-package-layout.md](references/skill-package-layout.md):目录约定、根 `SKILL.md` 各块格式、`pools`/`valves` 文字范例摘录 |
40
- | 门控脚本 API | [references/agentic-lab-sdk.md](references/agentic-lab-sdk.md)(生成 `scripts/*.js` 前必读) |
41
- | 门控脚本规范 | [references/agentic-lab-processer.md](references/agentic-lab-processer.md):`Processer` 类的 `start`/`complete` 输入输出类型定义与代码风格参考(参数与返回值均为 **snake_case**) |
42
- | **业务流程文档模板** | [templates/业务流程文档模板.md](templates/业务流程文档模板.md):空白模板,各章节带占位提示;用于「生成流程文档」模式 |
43
- | **业务流程文档示例** | [templates/业务流程文档示例.md](templates/业务流程文档示例.md):基于 Fragment 分装流程的填写示例,供参考 |
44
-
45
- ## 执行前确认
46
-
47
- 1. **输出目录**(按优先级):① 用户指定了具体路径 → 使用该路径;② 用户指定了流程说明文档路径 → 在文档所在目录下生成;③ 均未指定 → 在当前工作目录(CWD)下生成。**禁止**私自在任何子路径(如 `docs/`)下创建目录。`SKILL.md` 的 `name` 须与输出目录名一致(小写字母、数字、连字符,符合 Agent Skills 对 `name` 的约束)。
48
- 2. **流程条数**:一份流程说明对应一份流程注册包;多条流水线则分多个输出目录。
49
-
50
- ## 生成流程文档(仅「生成流程文档」模式)
51
-
52
- 当用户要求生成流程文档模板时,按以下步骤执行:
53
-
54
- 1. 读取 [templates/业务流程文档模板.md](templates/业务流程文档模板.md) 获取文档结构
55
- 2. 参考 [templates/业务流程文档示例.md](templates/业务流程文档示例.md) 了解各章节的填写规范
56
- 3. 根据用户描述的业务场景,预填充模板中的各章节(能确定的内容填入,不确定的保留占位提示)
57
- 4. 将文档写入用户指定路径(按优先级:① 用户指定了具体路径 → 使用该路径;② 用户指定了参考文档路径 → 在该文档所在目录下生成 `【流程文档】{流程名称}.md`;③ 均未指定 → 在当前工作目录下生成 `【流程文档】{流程名称}.md`。**禁止**私自创建子目录)
58
- 5. 提示用户:完善文档内容后,可直接用本技能的「初次生成」模式生成流程注册包
59
-
60
- **注意**:生成流程文档模式下**不执行**流程文档合规预检,也**不生成**流程注册包。
61
-
62
- ## 流程文档合规预检(阻断;仅「初次生成」)
63
-
64
- **适用**:仅当上文 **「会话模式判定」** 为 **初次生成** 时执行本节。**迭代修改** 模式下一整节跳过(不得要求用户提供流程说明以通过预检)。
65
-
66
- 在**初次**向目标输出目录创建 `SKILL.md`、`pools/`、`valves/`、`scripts/` 之前,必须完成本预检。
67
-
68
- ### 依据与范围
69
-
70
- - **依据**:[references/业务流程文档标准.md](references/业务流程文档标准.md) 全文,重点:**§1 文档级要求**、**§2 必备章节与检查点**、**§3(含 §3.1~§3.3:门控逻辑严谨性、SDK/字段可支持性、Process 与 SDK 参数格式)**、**§4 合规检查清单**;涉及 API 时须对照 [references/agentic-lab-sdk.md](references/agentic-lab-sdk.md)(及流程中已引用的 `references/rhea-api/` 文档)。
71
- - **对象**:用户指定的流程说明 Markdown(路径以对话约定为准)。
72
- - **章节编号**:若用户文档未使用 `## 1.` … `## 6.` 数字标题,仍须能**映射**到标准中 §1~§6 所描述的同等信息(缺失即判不通过并说明缺哪块语义)。
73
-
74
- ### 预检执行方式
75
-
76
- 1. 打开 [references/业务流程文档标准.md](references/业务流程文档标准.md),以 **§4 合规检查清单** 为主轴,逐项核对流程文档;对 §2 各小节**检查点**做交叉验证(池名/门控名/YAML/拓扑/字段表一致性等)。
77
- 2. **专项**:按标准 **§3.1~§3.3** 审查门控逻辑是否可判定、是否存在**不支持或未文档化的 API/字段**、Process/任务提交等调用的**参数与 JSON 形状**是否与 [references/agentic-lab-sdk.md](references/agentic-lab-sdk.md) 及 [references/rhea-api/](references/rhea-api/) 一致;发现问题须在《优化建议》中**单独小节**列出「不支持或不可生成项」。
78
- 3. 将每一项标为 **通过** / **不通过**;不通过须写明**标准条款**(可引用标准内小节标题或清单原文)。
79
-
80
- ### 若不通过(强制中止)
81
-
82
- - **禁止**写入目标输出目录下的流程注册包文件(含部分生成:不得先建空目录再补全)。
83
- - **必须**向用户交付 **《流程文档合规问题与优化建议》**(可用 Markdown 小节组织),且至少包含:
84
- 1. **问题清单**:每条对应标准中的位置(例如「§4 清单第 n 项」「§3.2 不支持的 API」「§3.3 `items` 结构不完整」)。
85
- 2. **现状说明**:流程文档中**缺失**、**矛盾**、**模糊**或**不可解析**之处(可引用现有标题、表格列名、YAML 片段;对不支持的依赖/API/字段须**点名**)。
86
- 3. **可执行修改建议**:具体应**补写/改写**哪一类内容(例如消除模糊条件、改为 SDK 已支持方法、补全 SDK 调用方法的参数说明、统一字段拼写)。
87
- 4. **严重程度**:**阻断**(不满足则无法稳定生成,含不支持的 API、不可判定逻辑、Process 参数无法落地)与**建议**(不阻断但易导致脚本/Schema 歧义)。
88
- 5. **(若适用)不支持或不可生成项**:集中列出标准 **§3.2 / §3.3** 拦截项,避免与一般格式问题混排。
89
- - 仅当用户**随后**提供已按建议修订的流程文档时,才允许重新从本预检开始执行。
90
-
91
- ### 若通过(仅初次生成)
92
-
93
- - 用 1~3 句话给出**预检通过摘要**(可列已通过的关键项),再进入 **「生成流程」**。
94
-
95
- ## 生成流程(按序执行)
96
-
97
- **前置条件**:
98
- - **初次生成**:已完成「流程文档合规预检」且结论为**通过**;未通过时**不得**执行本节任一步骤。
99
- - **迭代修改**:跳过预检;直接进入与本任务相关的文件修改(仍须符合 `skill-package-layout`、`agentic-lab-sdk` 等约定)。
100
-
101
- **迭代修改时**:不必从本节 **§1** 起做全量「解析—规划—写入」;按用户指定范围改 `SKILL.md` / `pools/` / `valves/` / `scripts/` 即可,且**不得**为通过预检而虚构流程说明。
102
-
103
- ### 1. 解析流程说明
104
-
105
- 从文档中提取结构化事实(勿臆造文档未写的池或门控):
106
-
107
- - **流程元信息**:流程标识、流程名称、版本、业务摘要。
108
- - **记录**:入口字段表;各门控富化字段分组。
109
- - **数据池**:显示名称、逻辑 ID、角色、业务含义。
110
- - **池间流转**:Mermaid 边与文字补充中的合流、分支语义;写入产出包 `## 流程图` 时,池须为矩形节点、门控须为六边形节点(见 §3.4)。
111
- - **门控**:每个门控的 `valve_id`/`gate_id`、`name`、`order`、`input`、`output` YAML 与检查规则表;若有 **化合物数据查询方式**、**字段映射**、**数据处理规则** 等小节,须单独抽取(写入对应 `valves/*.md` 与脚本注释)。若有操作员步骤则保留为业务步骤列表。
112
- - **门控三阶段**:每个门控可包含 **前置处理**、**人工处理**、**后置处理** 三个小节,对应门控执行顺序:`门控[前置处理]脚本 → [人工处理]页面 → 门控[后置处理]脚本`。
113
- - **前置处理** → 生成 `Processer.start` 函数逻辑。须提取:
114
- - 配置项表(如 `bookid`),用于拼装 `orbit_link`
115
- - 规则摘要表(条件要点 + 业务动作),落入 `start` 函数体
116
- - 数据处理规则(序号表),按序号写入脚本注释与实现
117
- - **人工处理** → 描述 Orbit 页面的界面形态与数据绑定(由 `lab-orbit-component-builder` 等技能负责生成 UI,门控脚本中不实现)。须提取:
118
- - 界面类型(超级表格、表单等)
119
- - 数据来源与操作按钮描述
120
- - **后置处理** → 生成 `Processer.complete` 函数逻辑。须提取:
121
- - 规则摘要表(条件要点 + 业务动作),落入 `complete` 函数体
122
- - 提交参数结构(如 SDK 调用方法的参数定义与键级说明)
123
- - 出口池路由条件与字段映射
124
- - **门控脚本配置项**:提取全局配置表中的各项,落入脚本为**模块级常量**:
125
- - `PageUrl`(含 `{bookid}` 占位符)→ 脚本常量 `PAGE_URL`
126
- - `StationBaseURL`(若有)→ 脚本常量 `STATION_BASE_URL`
127
- - `门控脚本对入口池单次查询上限`(若有,如 `9000`)→ 脚本常量 `DEFAULT_QUERY_LIMIT`(覆盖默认 `999999`)
128
- - 各门控**前置处理**配置项中的 `bookid` 该门控脚本常量 `BOOK_ID`(用于 `PAGE_URL.replace('{bookid}', BOOK_ID)` 拼装 `orbit_link`)
129
- - **知识库**(若有独立章节):字段级语义,供概述与注释引用。
130
-
131
- 章节编号以用户文档为准;上表按常见顺序列举要提取的内容。
132
-
133
- ### 2. 规划产物清单
134
-
135
- [`embedded-template/`](embedded-template/) 实际目录为准规划路径;细则见 [references/skill-package-layout.md](references/skill-package-layout.md) §1。
136
-
137
- - **Pool 文件数** = 数据池表行数;每个池一个 `pools/<显示名称>.md`,文件名与表中「显示名称」**逐字一致**(含标点、中间点「·」等)。
138
- - **Valve / Script 对** = 门控个数;每个门控生成同名一对:`valves/<基名>.md` 与 `scripts/<基名>.js`。
139
- - **`<基名>` 命名**:与 [references/skill-package-layout.md](references/skill-package-layout.md) §1 及 [`embedded-template/valves/`](embedded-template/valves/) 示例一致——取门控标题中的**稳定简短名**;含空格的英文片段去掉空格(例:`Process 发射判定` → `Process发射判定`);中文门控名若标题含「门控」则保留;若标题本身为简短名(如「查看结果与复核更新」)则文件名不硬加「门控」。
140
-
141
- ### 3. 写入根目录 `SKILL.md`
142
-
143
- 正文**章节顺序、标题层级、表格列名、连接关系写法、`Processer` 代码块、`## 使用方式` 三条**须与 [references/skill-package-layout.md](references/skill-package-layout.md) §2 一致;一级标题为流程名称(来自流程说明)。除 frontmatter 外,二级标题须**按此顺序**出现(缺一则视为未完成):
144
-
145
- `## 概述` `## 核心概念` `## 流程图`(图后紧跟 `**连接关系:**` 与编号列表)→ `## 节点清单` → `## 门控执行规范` → `## 使用方式`
146
-
147
- #### 3.1 YAML frontmatter
148
-
149
- 须符合 [Agent Skills 规范](https://agentskills.io/specification):
150
-
151
- - `name`:与输出文件夹名相同;小写字母、数字、连字符;不得连续 `--`,不得以连字符开头或结尾。
152
- - `description`:≤1024 字符;写清本流程做什么、何时使用该流程注册包(流程名、数据池、门控、实验/分装等关键词)。
153
-
154
- #### 3.2 `## 概述`
155
-
156
- 用流程说明中的**业务摘要**与**自动化/人工路径**事实,写 1~3 段话:业务目标、主要阶段、Pool 与 Valve 如何分工。不引入文档未写的系统名。
157
-
158
- #### 3.3 `## 核心概念`
159
-
160
- 固定两个三级标题,正文可结合本流程改写,语义须与模板一致:
161
-
162
- - **`### 数据池(Pool)`**:说明 Pool 存记录、每池有独立 Schema、随阶段变化。
163
- - **`### 门控(Valve)`**:说明每个 Valve 对应脚本、`Processer` 的 `start` / `complete` 职责分工。
164
- 另起简短列表说明执行引擎通过 `this.context` 暴露的能力,**仅写** [references/agentic-lab-sdk.md](references/agentic-lab-sdk.md)「可用方法一览」中已列出的方法名(按流程实际使用选取),**不要**抄写模板里已过期的成员名。
165
-
166
- #### 3.4 `## 流程图`(本节内须含「连接关系」列表,与模板一致)
167
-
168
- 本节**不要**单独再开 `## 连接关系` 一级标题;流程图与紧随其后的 `**连接关系:**` 列表格式见抽取文档 §2.3:
169
-
170
- 1. **流程图本体**
171
- - 优先使用 **Mermaid** `flowchart` / `graph`(代码块语言为 `mermaid`)。从流程说明拷贝图时,须**改写成下列节点形状约定**(与下文示例一致);若原文无图,则按拓扑**新画**一版。
172
- - **数据池(Pool)节点**:须为**四边形(矩形)**,语法 `节点ID[池显示名称]`(Mermaid 默认方括号即矩形)。
173
- - **门控(Valve)节点**:须为**六边形**,语法 `节点ID{{门控显示名称}}`(双花括号 `{{…}}`)。
174
- - 同一图中 `节点ID` 用简短英文/拼音/缩写(无空格),**括号内文字**与数据池表、门控标题的**显示名称**一致。
175
- - 若缺失或无法表达合流,可改用 **ASCII**;池仍用 `┌──┐` 类**矩形**框,门控用可辨认的**六角框线**(或宽矩形内首行标注「门控」)以示区别,标签与上同。
176
-
177
- **Mermaid 示例(形状约定):**
178
-
179
- ```mermaid
180
- flowchart LR
181
- in_pool[入口池示例]
182
- gate{{某门控标题示例}}
183
- out_pool[出口池示例]
184
- in_pool --> gate --> out_pool
185
- ```
186
-
187
- 生成时替换节点 ID 与中文标签为真实池名、门控名;复杂拓扑可 `subgraph` 分区,但**每个池仍为 `[…]`、每个门控仍为 `{{…}}`**。
188
-
189
- 2. **`**连接关系:**`**(加粗小标题,紧跟在流程图之后)
190
- 其下为**编号列表**,穷举拓扑中有向边对应的业务关系。每条格式与模板一致:
191
-
192
- `序号. \`源节点\` → \`目标节点\`:一句业务说明`
193
-
194
- 「节点」为**池显示名称**或**门控显示名称**(与流程说明一致)。生成规则:
195
-
196
- - **池 → 门控**:门控 `input.primary` / `input.secondary` 所指的池 → 该门控标题名。
197
- - **门控 → 池**:该门控 `output` 中每个分支 → 目标池显示名称。
198
- - 不合并为「池池」而省略门控名,除非文档本身只描述池间结果而未命名门控(此时仍应用文档中的门控名若存在)。
199
-
200
- 顺序建议按门控 `order` 或文档叙述;**全量列出**(含合流、异常池、终点池)。
201
-
202
- #### 3.5 `## 节点清单`
203
-
204
- - **`### Pool 节点(数据池)`**:Markdown 表格,列 **`名称` | `文件` | `用途`**。
205
- - `名称`:与 `pools/*.md` 文件名相同。
206
- - `文件`:Markdown 链接 `[pools/<名称>.md](pools/<名称>.md)`。
207
- - `用途`:来自数据池表「业务含义」或概述,一两句。
208
-
209
- - **`### Valve 节点(门控)`**:Markdown 表格,列 **`名称` | `文件` | `脚本` | `类型`**。
210
- - `名称`:与流程说明门控标题一致(可读名,可与 valve 文件名略有后缀差异时在「名称」列用完整名)。
211
- - `文件`:`[valves/<基名>.md](valves/<基名>.md)`。
212
- - `脚本`:`[scripts/<基名>.js](scripts/<基名>.js)`。
213
- - `类型`:流程说明中该门控以**操作员步骤/人工称量**为主则填 `人工操作`,否则填 `自动化`(与模板粒度一致;文档无暗示时默认 `自动化`)。
214
-
215
- #### 3.6 `## 门控执行规范`
216
-
217
- `Processer` 代码块**原文照抄** [references/skill-package-layout.md](references/skill-package-layout.md) §2.5:`constructor`、`async start`、`async complete` 及注释;不含导出语句。不在此节展开 `context` 各方法签名(见 [references/agentic-lab-sdk.md](references/agentic-lab-sdk.md))。
218
-
219
- #### 3.7 `## 使用方式`
220
-
221
- 固定 3 条编号步骤,语义对齐模板:查阅 `pools/` Schema、查阅 `valves/` 与脚本路径、执行门控时调用对应 `Processer`。
222
-
223
- ### 4. 写入每个 `pools/<显示名称>.md`
224
-
225
- 标题与表格格式对齐 [references/skill-package-layout.md](references/skill-package-layout.md) §3:`# 标题`、`## 概述`、`## Schema`(列名:**字段、字段标题、字段描述、字段类型、属性、默认值**,共六列)。
226
-
227
- - **概述**:该池在流程中的职责(数据池含义 + 拓扑位置)。
228
- - **Schema**
229
- - **字段行范围(按需)**:Schema 表**仅**收录流程说明中与本池记录**明确相关**的字段(如入口字段表、该池字段/列描述、某门控写明写入本池记录者)。**禁止**为对齐 `embedded-template` 或追求「表看起来完整」而增加流程文档未出现的业务字段行。
230
- - **字段**:机器可读键名,**必须**为 `a-z`、数字与下划线组成的 **snake_case**(全小写,如 `compound_id`、`target_amount_1_mg`)。由流程说明中的「字段名」映射而来:去掉空格与括号说明、统一小写、空格或混合写法改为下划线(例:`Compound ID` → `compound_id`,`Target Amount 1 (mg)` → `target_amount_1_mg`)。
231
- - **字段标题**:与流程说明或业务系统一致的**展示名**(可为英文短语如 `Compound ID`,或简短中文标题),供人读表与 UI 列头;**不要**把原「字段」列的英文混进「字段」列。
232
- - **字段描述**、**字段类型**、**属性**、**默认值**:规则同前(属性仍仅写枚举/格式归纳,无则留空)。
233
- - **属性列**:仅当流程说明对该字段给出了**可选值/枚举**(含「枚举:…」「如 A、B」、用顿号/逗号分隔的取值列表等)时,将归纳后的约束写入本列,**建议**以 `枚举:` 开头(例:`枚举:固体颗粒过大,流动性差,强吸水性,易结块,易粘黏,强静电吸附,液体`)。若说明仅在「说明」列内嵌枚举长句,可将枚举部分抽到「属性」,「字段描述」保留简短业务含义。若说明中约定了**日期或时间的表达格式**(如 ISO8601、`YYYYMMDD`、批次号中的日期段),以 `格式:` 开头写入本列。无枚举、无格式约定则**属性列留空**(不写 `-` 占位语)。业务含义仍以「字段描述」为主,避免在描述与属性中完全重复粘贴同一段长文。
234
-
235
- ### 5. 写入每个 `valves/<基名>.md`
236
-
237
- 章节与排版对齐抽取文档 §4,**至少**包含:`## 概述`(编号步骤)、`## 关联脚本`、`## 执行流程`、`## 输入/输出`。`输入/输出` 须与门控 YAML 的 `primary`/`secondary` 与各输出池**显示名称**一致,**勿**照搬范例中的池名。
238
-
239
- 若流程说明对某门控给出了下列块,须在对应 `valves/<基名>.md` 中**原样结构化呈现**(标题可用 `##` / `###`,便于脚本作者对照):
240
-
241
- - **门控 YAML**(`valve_id`、`name`、`order`、`input`、`output`);若文档使用 `Stash:` 等非标准键表示目标池,**保留原文**,并在 valve 文内加一句说明:实现时按 [agentic-lab-sdk.md](references/agentic-lab-sdk.md) 获取出口池,以返回的 `pool.name` 与**池显示名称**匹配。
242
- - **前置处理**(对应 `start`):提取配置项(如 `bookid`)、规则摘要表,说明 `start` 函数需执行的逻辑。
243
- - **人工处理**:界面形态与数据绑定描述(仅供参考,不由门控脚本实现)。
244
- - **后置处理**(对应 `complete`):规则摘要表、提交参数结构(如 SDK 调用方法的参数定义),说明 `complete` 函数需执行的逻辑。
245
- - **化合物数据查询方式**(或等价标题):表或段落中「查化合物库存」等表述,与 [references/agentic-lab-sdk.md](references/agentic-lab-sdk.md) 中对应 SDK 方法的映射关系写清。
246
- - **字段映射表**:「门控加工数据 库字段 / API 字段」;脚本写入 `ticket.detail` 的键须与 **pools Schema「字段」列(snake_case)** 一致。
247
- - **数据处理规则**表:序号(如 1.1、1.2)须在脚本注释中可逐条追溯。
248
-
249
- 参考范例:[embedded-template/valves/示例数据与校验门控.md](embedded-template/valves/示例数据与校验门控.md)。
250
-
251
- ### 6. 写入每个 `scripts/<基名>.js`
252
-
253
- 1. **先读** [references/agentic-lab-sdk.md](references/agentic-lab-sdk.md) 与 [references/agentic-lab-processer.md](references/agentic-lab-processer.md);`this.context` **仅**使用 sdk 文件已列出的成员;`start`/`complete` 的输入输出类型须对齐 processer 规范。
254
- 2. **结构**对齐 [embedded-template/scripts/示例数据与校验门控.js](embedded-template/scripts/示例数据与校验门控.js):`Processer` 类、`constructor(context)`、`async start` / `async complete`;脚本以类定义结束,禁止添加任何导出语句。示例中与本门控文档无关的业务分支**省略**。
255
- 3. **注释**与流程说明规则编号对应;业务分支处可用 `TODO`,**不得**编造文档未定义的池名或 API。
256
- 4. **实现逻辑**须遵循下文「门控脚本编写指引」(含 **`limit`/`offset` 默认全量** 约定)。
257
- 5. **按需生成**:详见下文「编写指引 §0」。
258
-
259
- ## 门控脚本编写指引
260
-
261
- 编写 `scripts/<基名>.js` 时,将流程说明中的**门控逻辑**与 **Agentic Lab SDK** 对齐,推荐顺序如下。
262
-
263
- ### 0. 按需生成(禁止冗余)
264
-
265
- - **代码**:只实现本门控流程说明中已写出的判定、外部查询、对 `ticket.detail` 的更新、出口路由;文档未写的 SDK 调用、辅助逻辑、占位字段一律不写。
266
- - **`ticket.detail` 键**:读写的 snake_case 键仅来自**字段映射**、**数据处理规则**或规则中显式引用的量;**禁止**新增文档未列出的业务键(含调试用 `_foo`、仅为对齐示例的附加键)。
267
- - **与 `embedded-template` 的关系**:**目录与 `Processer` 形态**可对齐;**具体调用的 `context` 方法与写入字段**以本门控文档为准,**禁止**整段拷贝示例脚本中与本门控无关的 compound / station / process 等逻辑。
268
-
269
- ### 1. 从流程说明抽取
270
-
271
- 下表各项**仅在该门控的流程说明中实际出现对应小节或规则时**才落入脚本;缺失则**不生成**该路径(或仅留 `TODO` 并在预检《优化建议》中提示文档缺口,**不得**臆造业务补全)。
272
-
273
- | 来源 | 落点(脚本侧) |
274
- |------|----------------|
275
- | 门控 YAML `input` | `start` 中按 [agentic-lab-sdk.md](references/agentic-lab-sdk.md) 查询入口池 tickets(`limit`/`offset` 遵守 §2);含 `secondary` 时合并多个入口池 ID |
276
- | 门控 YAML `output` | `complete` 中按 [agentic-lab-sdk.md](references/agentic-lab-sdk.md) 获取出口池,以 `pool.name` 与条件分支筛选目标池 |
277
- | **化合物数据查询方式** | 按 [agentic-lab-sdk.md](references/agentic-lab-sdk.md) 调用化合物库存查询方法 |
278
- | **字段映射表** | 将 API 返回字段写入 `ticket.detail` 的 snake_case 键 |
279
- | **数据处理规则**(序号表) | `start` 内计算与回填,或 `complete` 内最终路由前校验;关键分支写 `// 规则 1.x` 注释 |
280
- | **门控脚本配置项**表 | 脚本模块级常量:`PAGE_URL`(取 `PageUrl` 值)、`DEFAULT_QUERY_LIMIT`(取入口池查询上限,缺省 `999999`)、`STATION_BASE_URL`(若有);**各门控前置处理**配置中的 `bookid` → `BOOK_ID`(每个门控独立值) |
281
-
282
- ### 2. 分页与「查全量」(`limit` / `offset`)
283
-
284
- [references/agentic-lab-sdk.md](references/agentic-lab-sdk.md)「可用方法一览」中标注使用 `limit` / `offset` 分页的查询方法,生成门控脚本时遵守:
285
-
286
- 2. **流程说明写了分页**:按文档给出的 `limit`、`offset`(或等价参数名)原样写入调用。
287
- 3. **流程说明写了「查全部/不限制条数」及具体数值**(例如明确要求 `limit: 500000`):**以流程文档为准**,不得擅自改为 `999999`。
288
-
289
- ### 3. `start` 与 `complete` 分工(与门控三阶段对齐)
290
-
291
- 门控执行顺序为 **前置处理(脚本)→ 人工处理(页面)→ 后置处理(脚本)**。`start` 对应**前置处理**,`complete` 对应**后置处理**。
292
-
293
- **代码格式与风格**须严格对齐 [references/agentic-lab-processer.md](references/agentic-lab-processer.md) 中的类型定义:
294
-
295
- - **`start` 入参** `StartExecutionParams`:**必须**含 `valve_id`(`number`)、`pool_ids`(`number[]`);可通过 `[propName: string]: any` 扩展,但核心参数不可缺少或改名。
296
- - **`start` 返回** `StartExecutionResult`:**必须**含 `orbit_link`(`string`)、`ticket_ids`(`number[]`)。
297
- - **`complete` 入参** `CompleteExecutionParams`:**必须**含 `valve_id`(`number`)、`tickets`(`Record<string, any>[]`)。
298
- - **`complete` 返回** `CompleteExecutionResult`:通过 `new_tickets`(`Record<string, any>[]`,可选)返回待写入出口池的工单,由引擎自动创建。
299
- - **一级参数与返回值键名一律 snake_case**(如 `valve_id`、`pool_ids`、`ticket_ids`、`orbit_link`、`new_tickets`),**禁止** camelCase(如 ~~`ticketIds`~~、~~`poolIds`~~)。嵌套数据(如 `ticket.detail` 内容、SDK 方法的 `params`/`items` 等 JSON 结构)保持流程文档或 API 原有格式,不受此约束。
300
-
301
- - **`start(params)`**(对应**前置处理**):解构 **`valve_id`、`pool_ids`**(`Processer` 入参 snake_case)→ [agentic-lab-sdk.md](references/agentic-lab-sdk.md) 查询入口池数据(§2 默认大 `limit`)→ **仅当**流程说明前置处理中写明化合物查询 / 流程列表 / 工站等需求时,才按需调用对应 SDK 方法(缺则**不调**;各方法见 [agentic-lab-sdk.md](references/agentic-lab-sdk.md))→ **仅按**数据处理规则与映射更新 `ticket.detail` 中**文档涉及的键** → 按 SDK 更新 tickets(若确有写回)→ 拼装 `orbit_link`(见下方步骤)→ 返回 `{ orbit_link, ticket_ids }` 。
302
-
303
- **`orbit_link` 生成步骤**:
304
- 1. 从**门控脚本配置项**表提取 `PageUrl`(含 `{bookid}` 占位符),写为脚本模块级常量 `PAGE_URL`
305
- 2. 从该门控**前置处理**配置项中提取 `bookid` 值,写为脚本模块级常量 `BOOK_ID`
306
- 3. `start` 函数末尾拼装:`const orbit_link = PAGE_URL.replace('{bookid}', BOOK_ID)`
307
-
308
- - **`complete(params)`**(对应**后置处理**):解构 **`valve_id`** 与 **`tickets`**(snake_case 入参)→ **优先使用 `params.tickets` 作为业务数据源**(引擎已传入完整 ticket 数据,无需重新查询;仅当流程说明后置处理中**明确要求**获取额外数据或最新状态时才按需查询)→ 按流程说明后置处理中的规则执行业务逻辑(准备提交参数、按需调用 SDK 方法、判定成败等)→ 按 [agentic-lab-sdk.md](references/agentic-lab-sdk.md) 获取出口池 → 将入口池 tickets 更新为 `finished` → 按出口池条件映射 `new_tickets`(含 `flow_id`、`pool_id`、`order_id`、`detail`、`status: 'created'`、`parent_ticket_id`)→ 返回 `{ new_tickets }`(由引擎自动创建,**不**在脚本内直接追加 tickets)。
309
-
310
- ### 4. 运行环境约束(沙箱可用全局对象)
311
-
312
- 门控脚本在**沙箱**中执行,**仅**以下全局对象/函数可用:
313
-
314
- | 类别 | 可用 |
315
- |------|------|
316
- | 基础类型 | `Array`, `Object`, `Map`, `Set`, `JSON`, `Math`, `Date`, `Number`, `String`, `Boolean`, `RegExp` |
317
- | 错误类型 | `Error`, `TypeError`, `ReferenceError` |
318
- | 数值函数 | `parseInt`, `parseFloat`, `isNaN`, `isFinite` |
319
- | 编码函数 | `encodeURIComponent`, `decodeURIComponent`, `encodeURI`, `decodeURI` |
320
- | 异步 | `Promise`, `setTimeout`, `clearTimeout`, `setInterval`, `clearInterval` |
321
- | 常量 | `undefined`, `NaN`, `Infinity` |
322
- | IO | `console`(`log`/`info`/`warn`/`error`/`debug`)、`fetch`(仅限 SDK 无法覆盖的外部调用) |
323
-
324
- **不可用**(使用即抛 `ReferenceError`):
325
-
326
- - `URLSearchParams`、`URL`、`Headers`、`Request`、`Response`、`FormData`、`Blob`、`Buffer`
327
- - `TextEncoder`、`TextDecoder`
328
- - `process`、`require`、`module`、`exports`、`__dirname`、`__filename`
329
- - `window`、`document`、`globalThis`(浏览器/Node.js 专属)
330
-
331
- **替代方案**:
332
-
333
- 1. **拼接 query string**——用模板字符串 + `encodeURIComponent`(不要用 `URLSearchParams`):
334
- ```js
335
- // 正确
336
- const qs = `view_id=${encodeURIComponent(viewId)}&page_size=500`;
337
- const url = `${BASE}?${qs}`;
338
-
339
- // ❌ 错误——URLSearchParams 不存在
340
- const qs = new URLSearchParams({ view_id: viewId, page_size: '500' });
341
- ```
342
-
343
- 2. **外部 HTTP 调用**——优先使用 `this.context` SDK 方法(见 [references/agentic-lab-sdk.md](references/agentic-lab-sdk.md))。仅当流程文档要求调用 SDK 未覆盖的第三方 API(如飞书/Lark)时,才使用 `fetch`;此时 URL 手动拼接,**不依赖** `URLSearchParams`。
344
-
345
- 3. **JSON 序列化**——`JSON.stringify` / `JSON.parse` 可用(`JSON` 在沙箱白名单中)。
346
-
347
- ### 5. 类型安全的字段访问(防止运行时 TypeError)
348
-
349
- `ticket.detail` 的值为**任意 JSON 类型**(`string` / `number` / `boolean` / `array` / `object` / `null`)——即使 pool Schema 声明为 `text`,运行时也可能收到 `number` 或 `null`。**生成代码时须遵守**:
350
-
351
- 1. **禁止直接对 `detail` 值调用 `.trim()` / `.split()` / `.toLowerCase()` 等 `String.prototype` 方法**——若该值为 `number` 或 `null`,会抛出 `TypeError: xxx.trim is not a function`。
352
- 2. **字符串读取**:先用 `String()` 转换或 `typeof` 判断:
353
- ```js
354
- // 正确
355
- const barcode = String(detail.source_barcode ?? '');
356
- // ✅ 正确
357
- const barcode = detail.source_barcode != null ? String(detail.source_barcode) : '';
358
- // ❌ 错误——detail.source_barcode 可能为 number / null
359
- const barcode = detail.source_barcode.trim();
360
- ```
361
- 3. **数字读取**:先用 `Number()` 转换并检查 `Number.isFinite()`:
362
- ```js
363
- const amount = Number(detail.error_tolerance_mg);
364
- if (!Number.isFinite(amount)) { /* fallback */ }
365
- ```
366
- 4. **数组 / 对象读取**:先用 `Array.isArray()` `typeof === 'object'` 检查后再操作。
367
- 5. 若脚本内多处需要安全取值,可在模块级定义简短辅助函数(见 [embedded-template/scripts/示例数据与校验门控.js](embedded-template/scripts/示例数据与校验门控.js) 中的 `str()` / `num()`),减少重复模式。
368
-
369
- ### 6. 参考代码(按优先序打开)
370
-
371
- 1. [references/agentic-lab-processer.md](references/agentic-lab-processer.md)(**`Processer` 类型定义与代码风格**参考;`start`/`complete` 输入输出类型、snake_case 命名)
372
- 2. [embedded-template/scripts/示例数据与校验门控.js](embedded-template/scripts/示例数据与校验门控.js)(**结构与分页约定**参考;SDK 方法**仅当本门控文档需要时**才纳入生成,勿默认照抄示例中的全部调用;**列表类查询默认 `limit: 999999`**)
373
- 3. [references/agentic-lab-sdk.md](references/agentic-lab-sdk.md)
374
- 4. 多门控流程:按拓扑为每个门控各写一对 `valves/<基名>.md` 与 `scripts/<基名>.js`,API 与分页约定同上;勿使用 `agentic-lab-sdk.md` 未列出的 `context` 成员。
375
-
376
- ### 7. 产物版本追踪
377
-
378
- 每次生成或修改流程注册包时,**必须**在产物中维护版本信息,帮助用户识别产物来源和版本。
379
-
380
- #### 7.1 SKILL.md frontmatter 版本
381
-
382
- 生成的流程注册包 `SKILL.md` frontmatter **必须**包含 `metadata` 块:
383
-
384
- ```yaml
385
- ---
386
- name: <与根目录同名-kebab-case>
387
- description: <≤1024 字符>
388
- metadata:
389
- version: "<semver>"
390
- generated_by: lab-flow-designer
391
- generated_at: "<YYYY-MM-DD>"
392
- ---
393
- ```
394
-
395
- - **初次生成**:`version: "1.0.0"`,`generated_at` 为当天日期。
396
- - **迭代修改**:读取现有 `metadata.version`,按变更范围递增(patch:修复;minor:新增逻辑;major:输入输出结构变更),更新 `generated_at`。
397
-
398
- #### 7.2 脚本版本常量
399
-
400
- 每个 `scripts/<基名>.js` 在 doc comment 之后、`DEFAULT_QUERY_LIMIT` 等业务常量之前,**必须**包含:
401
-
402
- ```javascript
403
- // --- Artifact Version ---
404
- const __ARTIFACT_VERSION__ = '<与 SKILL.md metadata.version 一致>';
405
- const __ARTIFACT_SKILL__ = 'lab-flow-designer';
406
- ```
407
-
408
- 迭代修改时同步更新 `__ARTIFACT_VERSION__` 值。
409
-
410
- #### 7.3 构造函数版本打印
411
-
412
- `Processer` 的 `constructor` 中,`this.context = context;` 之后**必须**添加:
413
-
414
- ```javascript
415
- console.info(`[Processer] v${__ARTIFACT_VERSION__} (skill: ${__ARTIFACT_SKILL__})`);
416
- ```
417
-
418
- ## Gotchas
419
-
420
- 生成前快速检查清单(规则详见对应章节,此处仅提醒要点):
421
-
422
- - 合规预检仅「初次生成」时执行(见「会话模式判定」)
423
- - 列表查询默认 `limit: 999999`;门控脚本配置项有自定义上限时从其取(见「编写指引 §2」)
424
- - Pool Schema 须含六列(字段/字段标题/字段描述/字段类型/属性/默认值),字段列为 snake_case(见「生成流程 §4」)
425
- - 池文件名与数据池表「显示名称」逐字一致(见「生成流程 §2」)
426
- - Mermaid = 矩形 `[…]`、门控 = 六边形 `{{…}}`(见「生成流程 §3.4」)
427
- - 合流门控 `pool_ids` 须覆盖所有入口池(见「编写指引 §1」)
428
- - `context` 仅使用 [agentic-lab-sdk.md](references/agentic-lab-sdk.md) 已列方法,禁止虚构 API
429
- - start/complete 输入输出严格对齐 [agentic-lab-processer.md](references/agentic-lab-processer.md)(见「编写指引 §3」)
430
- - 一级参数/返回值 snake_case;嵌套 JSON 保持原格式(见「编写指引 §3」)
431
- - `orbit_link` = `PageUrl` + `bookid`(见「编写指引 §3 orbit_link 生成步骤」)
432
- - 门控三阶段:前置处理 → `start`、后置处理 → `complete`、人工处理 → UI 技能(见「解析流程说明 §1」)
433
- - `complete` 优先使用 `params.tickets`,非必要不重查(见「编写指引 §3」)
434
- - 脚本以 `Processer` 类结束,禁止 `return`/`module.exports`/`export`(见「生成流程 §6」)
435
- - 按需生成,禁止冗余:代码和 Schema 仅覆盖流程文档明确写出的内容(见「编写指引 §0」)
436
- - **类型安全**:禁止直接对 `ticket.detail` 值调用 `.trim()` / `.split()` 等字符串方法;必须先 `String()` 转换或 `typeof` 判断(见「编写指引 §5」)
437
- - **运行环境**:门控脚本在沙箱执行,`URLSearchParams`/`URL`/`Buffer` Web/Node API **不可用**;拼接 query string 须用模板字符串 + `encodeURIComponent`(见「编写指引 §4」)
438
- - **外部 HTTP**:优先用 `this.context` SDK 方法;仅 SDK 未覆盖的第三方 API 才用 `fetch`,URL 手动拼接(见「编写指引 §4」)
439
- - **产物版本**:SKILL.md frontmatter 须含 `metadata.version`;每个脚本须含 `__ARTIFACT_VERSION__` / `__ARTIFACT_SKILL__` 常量及 constructor `console.info`(见「编写指引 §7」)
440
- - **脚本自测**:凡写入或修改 `scripts/*.js`,必须用 `testing/test-processer.mjs` 执行自测并自动修复,直到正常轮全 `pass`(见「脚本自测」)
441
-
442
- ## 扩展
443
-
444
- 若一份说明含多条独立流水线,应对每条线各建一个输出目录与独立 `SKILL.md`(各自 `name`),勿混在同一包内。
445
-
446
- ## 验证生成结果
447
-
448
- 对**生成目录**(输出目录,即当前工作目录或用户指定的路径)逐项自检;下列**对照物均为本 skill 内路径**。
449
-
450
- **流程来源**:若该包为 **初次生成** 产物,源流程文档应已通过 **「流程文档合规预检」**;复查可对照 [references/业务流程文档标准.md](references/业务流程文档标准.md) §4。**迭代修改**路径无此强制要求。
451
- **结构清单**:根目录 `SKILL.md`(合法 `name`/`description`、固定二级标题:`概述`、`核心概念`、`流程图`、`节点清单`、`门控执行规范`、`使用方式`)、`**连接关系:**`、`### Pool 节点` / `### Valve 节点`、`Processer` 类与门控执行规范代码块、存在 `pools/` / `valves/` / `scripts/`、`valves` 与 `scripts` 同名成对、任取一个 `pools/*.md` 的 Schema 表头含 **字段** / **字段标题** / **属性** 且数据行「字段」列为 snake_case。
452
-
453
- **版本追踪**:`SKILL.md` frontmatter 含 `metadata.version` / `metadata.generated_by` / `metadata.generated_at`;每个 `scripts/*.js` `__ARTIFACT_VERSION__` 常量(值与 `metadata.version` 一致)和 `__ARTIFACT_SKILL__` 常量;`Processer` constructor 含 `console.info` 版本打印。
454
-
455
- **对照物**:[embedded-template/](embedded-template/)(已知良好缩小范例)、[references/skill-package-layout.md](references/skill-package-layout.md)、[references/agentic-lab-sdk.md](references/agentic-lab-sdk.md)。
456
-
457
- **说明**:若工作区根目录另有自动化校验 Shell,可自行对生成包运行;具体脚本名与参数以工作区为准,**不**写入本 skill 必读引用。内置 [`embedded-template/SKILL.md`](embedded-template/SKILL.md) 的 `name` 可与目录名 `embedded-template` **故意不一致**(仅示意)。
458
-
459
- ## 脚本自测(生成后必须执行)
460
-
461
- **适用**:**初次生成** 与 **迭代修改** 两种模式下,凡写入或修改了 `scripts/*.js`,都**必须**对涉及的脚本执行自测。全部正常轮 `pass` 后方可交付用户。
462
-
463
- ### 自测工具
464
-
465
- 本 skill 内置测试工具 [`testing/test-processer.mjs`](testing/test-processer.mjs),零外部依赖,直接通过 `node` 执行。
466
-
467
- ### 执行命令
468
-
469
- 对每个生成或修改的 `scripts/<基名>.js` 执行:
470
-
471
- ```bash
472
- node <本skill目录>/testing/test-processer.mjs \
473
- --script <输出目录>/scripts/<基名>.js \
474
- --pools-dir <输出目录>/pools \
475
- --valves-dir <输出目录>/valves \
476
- --valve-name <基名>
477
- ```
478
-
479
- ### 验证范围
480
-
481
- 工具分两轮 mock 执行,分开报告:
482
-
483
- | 轮次 | 检查内容 | 失败级别 |
484
- |------|---------|---------|
485
- | **语法检查** | JavaScript 语法正确性 | 阻断 |
486
- | **结构检查** | `Processer` 类存在,含 `constructor`、`start`、`complete` | 阻断 |
487
- | **正常轮 `start`** | 正常类型 mock 数据运行,检查返回 `{ orbit_link: string, ticket_ids: number[] }` | 阻断 |
488
- | **正常轮 `complete`** | 正常类型 mock 数据运行,检查返回 `{ new_tickets: [...] }` 结构正确 | 阻断 |
489
- | **对抗轮 `start` + `complete`** | 第 3 条 ticket 的 text 字段填为 number/null,验证类型安全编码 | 警告(不阻断) |
490
- | **合规审计** | SDK 方法白名单、列表查询 `limit`/`offset`、返回值 snake_case | 未知 SDK 方法→阻断;其余→警告 |
491
-
492
- ### 结果判定与自动修复
493
-
494
- 工具输出 JSON,`status` 为 `pass` 或 `fail`。
495
-
496
- **自动修复循环(最多 3 轮):**
497
-
498
- 1. 运行测试,读取输出 JSON
499
- 2. 若**正常轮有 `fail`**:
500
- a. 读取 `errors` 数组中的错误描述
501
- b. 对照下方「修复指引表」,在脚本中定位并修复问题
502
- c. 修复后**立即重新运行测试**
503
- d. 重复直到正常轮全部 `pass`(最多 3 轮)
504
- 3. 若**对抗轮有 `fail`**:
505
- a. 读取 `warnings`,检查是否为真实的类型安全隐患
506
- b. 若是:按「编写指引 §5」添加 `String()` / `Number()` 防御
507
- c. 若为误报(该字段在真实数据中不可能为 null/number):忽略
508
- 4. **3 轮后仍有正常轮 `fail`**:停止修复,向用户报告剩余问题及已尝试的修复
509
- 5. 所有正常轮 `pass` 后:向用户报告测试结果摘要(含对抗轮警告,如有)
510
-
511
- ### 修复指引表
512
-
513
- | 错误类型 | 错误示例 | 自动修复策略 |
514
- |---------|---------|------------|
515
- | `SyntaxError` | `Unexpected token` | 检查脚本语法,修正括号/引号/关键字错误 |
516
- | `TypeError: x.trim is not a function` | detail 值非字符串直接调 `.trim()` | 替换为 `String(x ?? '').trim()` 或用 `str()` 辅助函数 |
517
- | `TypeError: Cannot read properties of null` | 未做 null 检查 | 添加可选链 `?.` 或空值合并 `??` |
518
- | `start() 返回值缺 orbit_link` | `orbit_link must be string, got undefined` | 检查 `start` 返回语句,补全 `orbit_link` 字段 |
519
- | `start() 返回值缺 ticket_ids` | `ticket_ids must be array, got undefined` | 确保返回 `ticket_ids: tickets.map(t => t.id)` |
520
- | `complete() new_tickets 缺必填字段` | `new_tickets[0].pool_id must be number` | 检查 new_tickets 映射逻辑,补全 `flow_id`/`pool_id`/`order_id`/`detail`/`status` |
521
- | `Unknown SDK namespace/method` | `Unknown SDK method called: context.xxx.yyy` | 替换为 [agentic-lab-sdk.md](references/agentic-lab-sdk.md) 中已有的方法 |
522
- | `ticket.list called without limit` | `ticket.list called without explicit limit` | 添加 `limit: DEFAULT_QUERY_LIMIT, offset: 0` |
523
- | `camelCase key in return value` | `"ticketIds" is camelCase — must be snake_case` | 改为 `ticket_ids` 等 snake_case 键名 |
524
- | `Processer missing start() method` | 结构检查未通过 | 确保 `Processer` 类包含 `async start(params)` 方法 |
525
-
526
- ## 脚本预览(试运行)
527
-
528
- **定位**:自测验证脚本"对不对"(语法、结构、契约),预览验证脚本"做了什么"(SDK 调用链、数据变换、路由逻辑)——两者互补。自测必须先 `pass`,预览才有意义。预览结果不影响 `pass/fail` 判定。
529
-
530
- ### 何时使用
531
-
532
- - **初次生成后**:自测全部通过后,自动执行一次预览,将报告展示给用户确认
533
- - **用户提供样本数据时**:使用 `--data` 模式,用真实或半真实数据验证具体业务场景
534
- - **迭代修改脚本逻辑后**:重新预览确认变更效果
535
-
536
- ### 执行命令
537
-
538
- **自动生成数据**(从 pool schema 生成 5 条场景 tickets):
539
-
540
- ```bash
541
- node <本skill目录>/testing/test-processer.mjs \
542
- --preview \
543
- --script <输出目录>/scripts/<基名>.js \
544
- --pools-dir <输出目录>/pools \
545
- --valves-dir <输出目录>/valves \
546
- --valve-name <基名>
547
- ```
548
-
549
- **用户提供样本数据**:
550
-
551
- ```bash
552
- node <本skill目录>/testing/test-processer.mjs \
553
- --preview \
554
- --data <样本数据.json> \
555
- --script <输出目录>/scripts/<基名>.js \
556
- --pools-dir <输出目录>/pools \
557
- --valves-dir <输出目录>/valves \
558
- --valve-name <基名>
559
- ```
560
-
561
- ### 样本数据格式
562
-
563
- 用户只需提供 `detail` 对象,工具自动补全 `id`/`flow_id`/`pool_id`/`order_id`/`status`/`uuid`:
564
-
565
- ```json
566
- {
567
- "tickets": [
568
- { "detail": { "cmpd_id": "CA1078", "cas": "28022-43-7", "amount": 50 } },
569
- { "detail": { "cmpd_id": "CA1079", "cas": "12345-67-8", "amount": 120 } }
570
- ]
571
- }
572
- ```
573
-
574
- ### 场景数据生成指引
575
-
576
- 当用户未提供 `--data` 时,工具从 pool schema 自动生成场景 tickets。若 pool schema 字段较少(如仅 `id` + `detail`),自动生成的 tickets 可能无业务字段,导致脚本中依赖特定字段的分支不被触发。此时 agent 应:
577
-
578
- 1. 阅读门控的 `valves/<基名>.md` 中的「数据处理规则」
579
- 2. 提取脚本依赖的关键字段(如 `cmpd_id`、`process_ids`、`amount` 等)
580
- 3. 生成一份 `--data` JSON,字段值覆盖主要业务路径
581
- 4. 用 `--data` 模式重新预览,确认完整数据流
582
-
583
- ### 报告解读
584
-
585
- 预览报告包含以下关键信息,agent 应逐项核对:
586
-
587
- | 报告区域 | 关注点 |
588
- |----------|--------|
589
- | **SDK 调用链** | 调用顺序是否与流程文档描述一致;参数是否正确(如 `filter` 中的字段名、`limit` 值) |
590
- | **ticket.detail 变更** | 变更的字段是否与流程文档「数据处理规则」吻合;是否有意外的字段被覆盖 |
591
- | **start() 返回值** | `orbit_link` 格式正确;`ticket_ids` 包含所有处理的 tickets |
592
- | **数据路由** | tickets 是否按预期分流到对应出口池;池名、数量、status 是否正确 |
593
- | **执行摘要** | 确认 start/complete 均成功;检查「未调用的 SDK 方法」是否符合预期 |
1
+ ---
2
+ name: lab-flow-designer
3
+ description: >-
4
+ 根据流程说明 Markdown 初次生成流程注册包时,须先按 references/业务流程文档标准.md 做合规预检,不通过则不得写入产出包并须输出优化建议;对已存在的流程注册包做增量修改时跳过流程文档预检。
5
+ 也可根据用户描述生成符合规范的业务流程文档模板,供用户完善后用于流程注册包生成。
6
+ 产出与本 skill 内 embedded-template、references/skill-package-layout.md 版式同构;根 SKILL.md 须含概述、核心概念、流程图(Mermaid 池为矩形、门控为六边形)、连接关系、节点清单、门控执行规范、使用方式。
7
+ Use when scaffolding flow skills, valve scripts from gate YAML and compound KB rules, Processer start/complete/run from pipeline docs, or generating flow document templates.
8
+ license: Proprietary
9
+ metadata:
10
+ embedded-template-dir: embedded-template
11
+ package-shape-ref: references/skill-package-layout.md
12
+ ---
13
+
14
+ # 从流程说明生成流程注册包
15
+
16
+ ## 适用场景
17
+
18
+ - 用户提供**流程说明 Markdown**的路径,并需要在工作区中生成与模板**同构**的流程注册包:根级 `SKILL.md`、`pools/*.md`、`valves/*.md`、`scripts/*.js`;或在**已有流程注册包目录**上修改、增补上述文件。
19
+ - 用户希望生成一份**业务流程文档模板**,用于梳理和描述新的业务流程,完善后再用本技能生成流程注册包。
20
+
21
+ ## 会话模式判定(须先执行)
22
+
23
+ 根据用户意图选择模式;**不得**在「迭代修改」会话中强行要求流程文档预检。
24
+
25
+ | 模式 | 判定要点(满足其一即可倾向该模式) | 流程文档合规预检 |
26
+ |------|-----------------------------------|------------------|
27
+ | **初次生成** | 从流程说明**新建**整包:用户给出(或隐含)流程说明 `.md` 路径,且目标为**新建或清空后写入**完整 `SKILL.md` + `pools/` + `valves/` + `scripts/`;或用户明确要求「按流程文档生成流程注册包」「脚手架」等。 | **必须**:先完成下文「流程文档合规预检」且**通过**后,才允许进入「生成流程」。 |
28
+ | **迭代修改** | 在**已存在**的流程注册包根目录上工作:目录内已有符合布局的 `SKILL.md` 与 `pools/` / `valves/` / `scripts/`(或用户明确仅改其中部分文件);诉求为修脚本、改 Schema、改文案、对齐 agentic-lab-sdk、小范围结构调整等,**且**非「用一份流程说明从零重写全包」。 | **跳过**:不要求对照流程说明做合规预检;修改仍须遵守 [references/skill-package-layout.md](references/skill-package-layout.md)、[references/agentic-lab-sdk.md](references/agentic-lab-sdk.md) 等本 skill 内条文。 |
29
+ | **生成流程文档** | 用户要求生成流程文档、流程模板、业务流程描述文档 | 基于模板和用户描述,生成预填充的业务流程文档并写入本地文件;**不生成**流程注册包。 |
30
+
31
+ **模糊时**:若用户同时给出流程说明路径与已有包路径,且表述为「用新流程说明**整体替换**本包」,按 **初次生成** 处理(须预检新流程文档);若仅「在某某包上改一下门控脚本」,按 **迭代修改** 处理。
32
+
33
+ ## 输入材料
34
+
35
+ | 材料 | 说明 |
36
+ |------|------|
37
+ | 流程说明 | **仅「初次生成」模式**下必用:用户指定的 `.md` 文件;须先通过「流程文档合规预检」([references/业务流程文档标准.md](references/业务流程文档标准.md)),未通过不得进入「生成流程」。**「迭代修改」模式**可不引用流程说明文件 |
38
+ | **极简目录范例(优先打开)** | 本 skill 内 [`embedded-template/`](embedded-template/):2 池 + 1 门控;[`embedded-template/valves/示例数据与校验门控.md`](embedded-template/valves/示例数据与校验门控.md) 与 [`embedded-template/scripts/示例数据与校验门控.js`](embedded-template/scripts/示例数据与校验门控.js) 含「数据查询 / 映射 / 规则」与 SDK 对齐的完整参考 |
39
+ | **版式条文** | [references/skill-package-layout.md](references/skill-package-layout.md):目录约定、根 `SKILL.md` 各块格式、`pools`/`valves` 文字范例摘录 |
40
+ | 门控脚本 API | [references/agentic-lab-sdk.md](references/agentic-lab-sdk.md)(生成 `scripts/*.js` 前必读) |
41
+ | 门控脚本规范 | [references/agentic-lab-processer.md](references/agentic-lab-processer.md):`Processer` 类的 `start`/`complete`(人工触发)与 `run`(自动触发)输入输出类型定义与代码风格参考(参数与返回值均为 **snake_case**) |
42
+ | **业务流程文档模板** | [templates/业务流程文档模板.md](templates/业务流程文档模板.md):空白模板,各章节带占位提示;用于「生成流程文档」模式 |
43
+ | **业务流程文档示例** | [templates/业务流程文档示例.md](templates/业务流程文档示例.md):基于 Fragment 分装流程的填写示例,供参考 |
44
+
45
+ ## 执行前确认
46
+
47
+ 1. **输出目录**(按优先级):① 用户指定了具体路径 → 使用该路径;② 用户指定了流程说明文档路径 → 在文档所在目录下生成;③ 均未指定 → 在当前工作目录(CWD)下生成。**禁止**私自在任何子路径(如 `docs/`)下创建目录。`SKILL.md` 的 `name` 须与输出目录名一致(小写字母、数字、连字符,符合 Agent Skills 对 `name` 的约束)。
48
+ 2. **流程条数**:一份流程说明对应一份流程注册包;多条流水线则分多个输出目录。
49
+
50
+ ## 生成流程文档(仅「生成流程文档」模式)
51
+
52
+ 当用户要求生成流程文档模板时,按以下步骤执行:
53
+
54
+ 1. 读取 [templates/业务流程文档模板.md](templates/业务流程文档模板.md) 获取文档结构
55
+ 2. 参考 [templates/业务流程文档示例.md](templates/业务流程文档示例.md) 了解各章节的填写规范
56
+ 3. 根据用户描述的业务场景,预填充模板中的各章节(能确定的内容填入,不确定的保留占位提示)
57
+ 4. 将文档写入用户指定路径(按优先级:① 用户指定了具体路径 → 使用该路径;② 用户指定了参考文档路径 → 在该文档所在目录下生成 `【流程文档】{流程名称}.md`;③ 均未指定 → 在当前工作目录下生成 `【流程文档】{流程名称}.md`。**禁止**私自创建子目录)
58
+ 5. 提示用户:完善文档内容后,可直接用本技能的「初次生成」模式生成流程注册包
59
+
60
+ **注意**:生成流程文档模式下**不执行**流程文档合规预检,也**不生成**流程注册包。
61
+
62
+ ## 流程文档合规预检(阻断;仅「初次生成」)
63
+
64
+ **适用**:仅当上文 **「会话模式判定」** 为 **初次生成** 时执行本节。**迭代修改** 模式下一整节跳过(不得要求用户提供流程说明以通过预检)。
65
+
66
+ 在**初次**向目标输出目录创建 `SKILL.md`、`pools/`、`valves/`、`scripts/` 之前,必须完成本预检。
67
+
68
+ ### 依据与范围
69
+
70
+ - **依据**:[references/业务流程文档标准.md](references/业务流程文档标准.md) 全文,重点:**§1 文档级要求**、**§2 必备章节与检查点**、**§3(含 §3.1~§3.3:门控逻辑严谨性、SDK/字段可支持性、Process 与 SDK 参数格式)**、**§4 合规检查清单**;涉及 API 时须对照 [references/agentic-lab-sdk.md](references/agentic-lab-sdk.md)(及流程中已引用的 `references/rhea-api/` 文档)。
71
+ - **对象**:用户指定的流程说明 Markdown(路径以对话约定为准)。
72
+ - **章节编号**:若用户文档未使用 `## 1.` … `## 6.` 数字标题,仍须能**映射**到标准中 §1~§6 所描述的同等信息(缺失即判不通过并说明缺哪块语义)。
73
+
74
+ ### 预检执行方式
75
+
76
+ 1. 打开 [references/业务流程文档标准.md](references/业务流程文档标准.md),以 **§4 合规检查清单** 为主轴,逐项核对流程文档;对 §2 各小节**检查点**做交叉验证(池名/门控名/YAML/拓扑/字段表一致性等)。
77
+ 2. **专项**:按标准 **§3.1~§3.3** 审查门控逻辑是否可判定、是否存在**不支持或未文档化的 API/字段**、Process/任务提交等调用的**参数与 JSON 形状**是否与 [references/agentic-lab-sdk.md](references/agentic-lab-sdk.md) 及 [references/rhea-api/](references/rhea-api/) 一致;发现问题须在《优化建议》中**单独小节**列出「不支持或不可生成项」。
78
+ 3. 将每一项标为 **通过** / **不通过**;不通过须写明**标准条款**(可引用标准内小节标题或清单原文)。
79
+
80
+ ### 若不通过(强制中止)
81
+
82
+ - **禁止**写入目标输出目录下的流程注册包文件(含部分生成:不得先建空目录再补全)。
83
+ - **必须**向用户交付 **《流程文档合规问题与优化建议》**(可用 Markdown 小节组织),且至少包含:
84
+ 1. **问题清单**:每条对应标准中的位置(例如「§4 清单第 n 项」「§3.2 不支持的 API」「§3.3 `items` 结构不完整」)。
85
+ 2. **现状说明**:流程文档中**缺失**、**矛盾**、**模糊**或**不可解析**之处(可引用现有标题、表格列名、YAML 片段;对不支持的依赖/API/字段须**点名**)。
86
+ 3. **可执行修改建议**:具体应**补写/改写**哪一类内容(例如消除模糊条件、改为 SDK 已支持方法、补全 SDK 调用方法的参数说明、统一字段拼写)。
87
+ 4. **严重程度**:**阻断**(不满足则无法稳定生成,含不支持的 API、不可判定逻辑、Process 参数无法落地)与**建议**(不阻断但易导致脚本/Schema 歧义)。
88
+ 5. **(若适用)不支持或不可生成项**:集中列出标准 **§3.2 / §3.3** 拦截项,避免与一般格式问题混排。
89
+ - 仅当用户**随后**提供已按建议修订的流程文档时,才允许重新从本预检开始执行。
90
+
91
+ ### 若通过(仅初次生成)
92
+
93
+ - 用 1~3 句话给出**预检通过摘要**(可列已通过的关键项),再进入 **「生成流程」**。
94
+
95
+ ## 生成流程(按序执行)
96
+
97
+ **前置条件**:
98
+ - **初次生成**:已完成「流程文档合规预检」且结论为**通过**;未通过时**不得**执行本节任一步骤。
99
+ - **迭代修改**:跳过预检;直接进入与本任务相关的文件修改(仍须符合 `skill-package-layout`、`agentic-lab-sdk` 等约定)。
100
+
101
+ **迭代修改时**:不必从本节 **§1** 起做全量「解析—规划—写入」;按用户指定范围改 `SKILL.md` / `pools/` / `valves/` / `scripts/` 即可,且**不得**为通过预检而虚构流程说明。
102
+
103
+ ### 1. 解析流程说明
104
+
105
+ 从文档中提取结构化事实(勿臆造文档未写的池或门控):
106
+
107
+ - **流程元信息**:流程标识、流程名称、版本、业务摘要。
108
+ - **记录**:入口字段表;各门控富化字段分组。
109
+ - **数据池**:显示名称、逻辑 ID、角色、业务含义。
110
+ - **池间流转**:Mermaid 边与文字补充中的合流、分支语义;写入产出包 `## 流程图` 时,池须为矩形节点、门控须为六边形节点(见 §3.4)。
111
+ - **门控**:每个门控的 `valve_id`/`gate_id`、`name`、`order`、`input`、`output` YAML 与检查规则表;若有 **化合物数据查询方式**、**字段映射**、**数据处理规则** 等小节,须单独抽取(写入对应 `valves/*.md` 与脚本注释)。若有操作员步骤则保留为业务步骤列表。
112
+ - **门控三阶段**:每个门控可包含 **前置处理**、**人工处理**、**后置处理** 三个小节,对应门控执行顺序:`门控[前置处理]脚本 → [人工处理]页面 → 门控[后置处理]脚本`。
113
+ - **前置处理** → 生成 `Processer.start` 函数逻辑。须提取:
114
+ - 配置项表(如 `bookid`),用于拼装 `orbit_link`
115
+ - 规则摘要表(条件要点 + 业务动作),落入 `start` 函数体
116
+ - 数据处理规则(序号表),按序号写入脚本注释与实现
117
+ - **人工处理** → 描述 Orbit 页面的界面形态与数据绑定(由 `lab-orbit-component-builder` 等技能负责生成 UI,门控脚本中不实现)。须提取:
118
+ - 界面类型(超级表格、表单等)
119
+ - 数据来源与操作按钮描述
120
+ - **后置处理** → 生成 `Processer.complete` 函数逻辑。须提取:
121
+ - 规则摘要表(条件要点 + 业务动作),落入 `complete` 函数体
122
+ - 提交参数结构(如 SDK 调用方法的参数定义与键级说明)
123
+ - 出口池路由条件与字段映射
124
+ - **触发方式**:每个门控的 `### 触发方式`(`自动触发` 或 `人工触发`)。自动触发门控无人工处理阶段,脚本实现 `run`(见 [references/agentic-lab-processer.md](references/agentic-lab-processer.md));人工触发门控保持 `start` + `complete`。
125
+ - **模型引用**(若有):数据池或门控的 `### 模型引用`(模型名称与版本),写入对应 `pools/*.md` `valves/*.md` `## 模型引用` 章节;无模型引用时省略。
126
+ - **门控脚本配置项**:提取全局配置表中的各项,落入脚本为**模块级常量**:
127
+ - `PageUrl`(含 `{bookid}` 占位符)→ 脚本常量 `PAGE_URL`
128
+ - `StationBaseURL`(若有)→ 脚本常量 `STATION_BASE_URL`
129
+ - `门控脚本对入口池单次查询上限`(若有,如 `9000`)→ 脚本常量 `DEFAULT_QUERY_LIMIT`(覆盖默认 `999999`)
130
+ - 各门控**前置处理**配置项中的 `bookid` → 该门控脚本常量 `BOOK_ID`(用于 `PAGE_URL.replace('{bookid}', BOOK_ID)` 拼装 `orbit_link`)
131
+ - **知识库**(若有独立章节):字段级语义,供概述与注释引用。
132
+
133
+ 章节编号以用户文档为准;上表按常见顺序列举要提取的内容。
134
+
135
+ ### 2. 规划产物清单
136
+
137
+ 以 [`embedded-template/`](embedded-template/) 实际目录为准规划路径;细则见 [references/skill-package-layout.md](references/skill-package-layout.md) §1。
138
+
139
+ - **Pool 文件数** = 数据池表行数;每个池一个 `pools/<显示名称>.md`,文件名与表中「显示名称」**逐字一致**(含标点、中间点「·」等)。
140
+ - **Valve / Script 对** = 门控个数;每个门控生成同名一对:`valves/<基名>.md` 与 `scripts/<基名>.js`。
141
+ - **`<基名>` 命名**:与 [references/skill-package-layout.md](references/skill-package-layout.md) §1 及 [`embedded-template/valves/`](embedded-template/valves/) 示例一致——取门控标题中的**稳定简短名**;含空格的英文片段去掉空格(例:`Process 发射判定` → `Process发射判定`);中文门控名若标题含「门控」则保留;若标题本身为简短名(如「查看结果与复核更新」)则文件名不硬加「门控」。
142
+
143
+ ### 3. 写入根目录 `SKILL.md`
144
+
145
+ 正文**章节顺序、标题层级、表格列名、连接关系写法、`Processer` 代码块、`## 使用方式` 三条**须与 [references/skill-package-layout.md](references/skill-package-layout.md) §2 一致;一级标题为流程名称(来自流程说明)。除 frontmatter 外,二级标题须**按此顺序**出现(缺一则视为未完成):
146
+
147
+ `## 概述` `## 核心概念` → `## 流程图`(图后紧跟 `**连接关系:**` 与编号列表)→ `## 节点清单` → `## 门控执行规范` → `## 使用方式`
148
+
149
+ #### 3.1 YAML frontmatter
150
+
151
+ 须符合 [Agent Skills 规范](https://agentskills.io/specification):
152
+
153
+ - `name`:与输出文件夹名相同;小写字母、数字、连字符;不得连续 `--`,不得以连字符开头或结尾。
154
+ - `description`:≤1024 字符;写清本流程做什么、何时使用该流程注册包(流程名、数据池、门控、实验/分装等关键词)。
155
+
156
+ #### 3.2 `## 概述`
157
+
158
+ 用流程说明中的**业务摘要**与**自动化/人工路径**事实,写 1~3 段话:业务目标、主要阶段、Pool 与 Valve 如何分工。不引入文档未写的系统名。
159
+
160
+ #### 3.3 `## 核心概念`
161
+
162
+ 固定两个三级标题,正文可结合本流程改写,语义须与模板一致:
163
+
164
+ - **`### 数据池(Pool)`**:说明 Pool 存记录、每池有独立 Schema、随阶段变化。
165
+ - **`### 门控(Valve)`**:说明每个 Valve 对应脚本、`Processer` 的 `start` / `complete`(人工触发)或 `run`(自动触发)职责分工。
166
+ 另起简短列表说明执行引擎通过 `this.context` 暴露的能力,**仅写** [references/agentic-lab-sdk.md](references/agentic-lab-sdk.md)「可用方法一览」中已列出的方法名(按流程实际使用选取),**不要**抄写模板里已过期的成员名。
167
+
168
+ #### 3.4 `## 流程图`(本节内须含「连接关系」列表,与模板一致)
169
+
170
+ 本节**不要**单独再开 `## 连接关系` 一级标题;流程图与紧随其后的 `**连接关系:**` 列表格式见抽取文档 §2.3:
171
+
172
+ 1. **流程图本体**
173
+ - 优先使用 **Mermaid** `flowchart` / `graph`(代码块语言为 `mermaid`)。从流程说明拷贝图时,须**改写成下列节点形状约定**(与下文示例一致);若原文无图,则按拓扑**新画**一版。
174
+ - **数据池(Pool)节点**:须为**四边形(矩形)**,语法 `节点ID[池显示名称]`(Mermaid 默认方括号即矩形)。
175
+ - **门控(Valve)节点**:须为**六边形**,语法 `节点ID{{门控显示名称}}`(双花括号 `{{…}}`)。
176
+ - 同一图中 `节点ID` 用简短英文/拼音/缩写(无空格),**括号内文字**与数据池表、门控标题的**显示名称**一致。
177
+ - 若缺失或无法表达合流,可改用 **ASCII**;池仍用 `┌──┐` 类**矩形**框,门控用可辨认的**六角框线**(或宽矩形内首行标注「门控」)以示区别,标签与上同。
178
+
179
+ **Mermaid 示例(形状约定):**
180
+
181
+ ```mermaid
182
+ flowchart LR
183
+ in_pool[入口池示例]
184
+ gate{{某门控标题示例}}
185
+ out_pool[出口池示例]
186
+ in_pool --> gate --> out_pool
187
+ ```
188
+
189
+ 生成时替换节点 ID 与中文标签为真实池名、门控名;复杂拓扑可 `subgraph` 分区,但**每个池仍为 `[…]`、每个门控仍为 `{{…}}`**。
190
+
191
+ 2. **`**连接关系:**`**(加粗小标题,紧跟在流程图之后)
192
+ 其下为**编号列表**,穷举拓扑中有向边对应的业务关系。每条格式与模板一致:
193
+
194
+ `序号. \`源节点\` → \`目标节点\`:一句业务说明`
195
+
196
+ 「节点」为**池显示名称**或**门控显示名称**(与流程说明一致)。生成规则:
197
+
198
+ - **池门控**:门控 `input.primary` / `input.secondary` 所指的池 → 该门控标题名。
199
+ - **门控 → 池**:该门控 `output` 中每个分支 → 目标池显示名称。
200
+ - 不合并为「池 → 池」而省略门控名,除非文档本身只描述池间结果而未命名门控(此时仍应用文档中的门控名若存在)。
201
+
202
+ 顺序建议按门控 `order` 或文档叙述;**全量列出**(含合流、异常池、终点池)。
203
+
204
+ #### 3.5 `## 节点清单`
205
+
206
+ - **`### Pool 节点(数据池)`**:Markdown 表格,列 **`名称` | `文件` | `用途`**。
207
+ - `名称`:与 `pools/*.md` 文件名相同。
208
+ - `文件`:Markdown 链接 `[pools/<名称>.md](pools/<名称>.md)`。
209
+ - `用途`:来自数据池表「业务含义」或概述,一两句。
210
+
211
+ - **`### Valve 节点(门控)`**:Markdown 表格,列 **`名称` | `文件` | `脚本` | `类型`**。
212
+ - `名称`:与流程说明门控标题一致(可读名,可与 valve 文件名略有后缀差异时在「名称」列用完整名)。
213
+ - `文件`:`[valves/<基名>.md](valves/<基名>.md)`。
214
+ - `脚本`:`[scripts/<基名>.js](scripts/<基名>.js)`。
215
+ - `类型`:流程说明中该门控以**操作员步骤/人工称量**为主则填 `人工操作`,否则填 `自动化`(与模板粒度一致;文档无暗示时默认 `自动化`)。
216
+
217
+ #### 3.6 `## 门控执行规范`
218
+
219
+ `Processer` 代码块**原文照抄** [references/skill-package-layout.md](references/skill-package-layout.md) §2.5:人工触发门控使用 `constructor`、`async start`、`async complete`;自动触发门控使用 `constructor`、`async run`;不含导出语句。不在此节展开 `context` 各方法签名(见 [references/agentic-lab-sdk.md](references/agentic-lab-sdk.md))。
220
+
221
+ #### 3.7 `## 使用方式`
222
+
223
+ 固定 3 条编号步骤,语义对齐模板:查阅 `pools/` Schema、查阅 `valves/` 与脚本路径、执行门控时调用对应 `Processer`。
224
+
225
+ ### 4. 写入每个 `pools/<显示名称>.md`
226
+
227
+ 标题与表格格式对齐 [references/skill-package-layout.md](references/skill-package-layout.md) §3:`# 标题`、`## 概述`、`## Schema`(列名:**字段、字段标题、字段描述、字段类型、属性、默认值**,共六列)。
228
+
229
+ - **概述**:该池在流程中的职责(数据池含义 + 拓扑位置)。
230
+ - **Schema**
231
+ - **字段行范围(按需)**:Schema 表**仅**收录流程说明中与本池记录**明确相关**的字段(如入口字段表、该池字段/列描述、某门控写明写入本池记录者)。**禁止**为对齐 `embedded-template` 或追求「表看起来完整」而增加流程文档未出现的业务字段行。
232
+ - **字段**:机器可读键名,**必须**为 `a-z`、数字与下划线组成的 **snake_case**(全小写,如 `compound_id`、`target_amount_1_mg`)。由流程说明中的「字段名」映射而来:去掉空格与括号说明、统一小写、空格或混合写法改为下划线(例:`Compound ID` → `compound_id`,`Target Amount 1 (mg)` → `target_amount_1_mg`)。
233
+ - **字段标题**:与流程说明或业务系统一致的**展示名**(可为英文短语如 `Compound ID`,或简短中文标题),供人读表与 UI 列头;**不要**把原「字段」列的英文混进「字段」列。
234
+ - **字段描述**、**字段类型**、**属性**、**默认值**:规则同前(属性仍仅写枚举/格式归纳,无则留空)。
235
+ - **属性列**:仅当流程说明对该字段给出了**可选值/枚举**(含「枚举:…」「如 A、B」、用顿号/逗号分隔的取值列表等)时,将归纳后的约束写入本列,**建议**以 `枚举:` 开头(例:`枚举:固体颗粒过大,流动性差,强吸水性,易结块,易粘黏,强静电吸附,液体`)。若说明仅在「说明」列内嵌枚举长句,可将枚举部分抽到「属性」,「字段描述」保留简短业务含义。若说明中约定了**日期或时间的表达格式**(如 ISO8601、`YYYYMMDD`、批次号中的日期段),以 `格式:` 开头写入本列。无枚举、无格式约定则**属性列留空**(不写 `-` 占位语)。业务含义仍以「字段描述」为主,避免在描述与属性中完全重复粘贴同一段长文。
236
+ - **模型引用**(若流程说明为该池指定了 3D 模型):在 `## Schema` 之后添加 `## 模型引用`,含模型名称与版本(格式见 [references/skill-package-layout.md](references/skill-package-layout.md) §3)。无模型引用时省略。
237
+
238
+ ### 5. 写入每个 `valves/<基名>.md`
239
+
240
+ 章节与排版对齐抽取文档 §4,**至少**包含:`## 概述`(编号步骤)、`## 关联脚本`、`## 触发方式`、`## 执行流程`、`## 输入/输出`。`输入/输出` 须与门控 YAML 的 `primary`/`secondary` 与各输出池**显示名称**一致,**勿**照搬范例中的池名。
241
+
242
+ 若流程说明对某门控给出了下列块,须在对应 `valves/<基名>.md` 中**原样结构化呈现**(标题可用 `##` / `###`,便于脚本作者对照):
243
+
244
+ - **触发方式**:`## 触发方式`,取值 `自动触发` `人工触发`,置于 `## 关联脚本` 之后。
245
+ - **模型引用**(若流程说明指定了模型):`## 模型引用`,含模型名称与版本。无模型引用时省略。
246
+ - **门控 YAML**(`valve_id`、`name`、`order`、`input`、`output`);若文档使用 `Stash:` 等非标准键表示目标池,**保留原文**,并在 valve 文内加一句说明:实现时按 [agentic-lab-sdk.md](references/agentic-lab-sdk.md) 获取出口池,以返回的 `pool.name` 与**池显示名称**匹配。
247
+ - **前置处理**(对应 `start`):提取配置项(如 `bookid`)、规则摘要表,说明 `start` 函数需执行的逻辑。
248
+ - **人工处理**:界面形态与数据绑定描述(仅供参考,不由门控脚本实现)。
249
+ - **后置处理**(对应 `complete`):规则摘要表、提交参数结构(如 SDK 调用方法的参数定义),说明 `complete` 函数需执行的逻辑。
250
+ - **化合物数据查询方式**(或等价标题):表或段落中「查化合物库存」等表述,与 [references/agentic-lab-sdk.md](references/agentic-lab-sdk.md) 中对应 SDK 方法的映射关系写清。
251
+ - **字段映射表**:「门控加工数据 库字段 / API 字段」;脚本写入 `ticket.detail` 的键须与 **pools Schema「字段」列(snake_case)** 一致。
252
+ - **数据处理规则**表:序号(如 1.1、1.2)须在脚本注释中可逐条追溯。
253
+
254
+ 参考范例:[embedded-template/valves/示例数据与校验门控.md](embedded-template/valves/示例数据与校验门控.md)
255
+
256
+ ### 6. 写入每个 `scripts/<基名>.js`
257
+
258
+ 1. **先读** [references/agentic-lab-sdk.md](references/agentic-lab-sdk.md) 与 [references/agentic-lab-processer.md](references/agentic-lab-processer.md);`this.context` **仅**使用 sdk 文件已列出的成员;`start`/`complete`(或 `run`)的输入输出类型须对齐 processer 规范。
259
+ 2. **结构**对齐 [embedded-template/scripts/示例数据与校验门控.js](embedded-template/scripts/示例数据与校验门控.js):`Processer` 类、`constructor(context)`、`async start` / `async complete`(人工触发)或 `async run`(自动触发);脚本以类定义结束,禁止添加任何导出语句。示例中与本门控文档无关的业务分支**省略**。
260
+ 2.5. **触发方式分支**:读取对应 `valves/<基名>.md` 中的 `## 触发方式`。若为 **人工触发** → 脚本结构同现有(`constructor` + `start` + `complete`);若为 **自动触发** → 脚本使用 `constructor` + `run`(类型定义见 [references/agentic-lab-processer.md](references/agentic-lab-processer.md)),不含 `start` 或 `complete`。
261
+ 3. **注释**与流程说明规则编号对应;业务分支处可用 `TODO`,**不得**编造文档未定义的池名或 API。
262
+ 4. **实现逻辑**须遵循下文「门控脚本编写指引」(含 **`limit`/`offset` 默认全量** 约定)。
263
+ 5. **按需生成**:详见下文「编写指引 §0」。
264
+
265
+ ## 门控脚本编写指引
266
+
267
+ 编写 `scripts/<基名>.js` 时,将流程说明中的**门控逻辑**与 **Agentic Lab SDK** 对齐,推荐顺序如下。
268
+
269
+ ### 0. 按需生成(禁止冗余)
270
+
271
+ - **代码**:只实现本门控流程说明中已写出的判定、外部查询、对 `ticket.detail` 的更新、出口路由;文档未写的 SDK 调用、辅助逻辑、占位字段一律不写。
272
+ - **`ticket.detail` 键**:读写的 snake_case 键仅来自**字段映射**、**数据处理规则**或规则中显式引用的量;**禁止**新增文档未列出的业务键(含调试用 `_foo`、仅为对齐示例的附加键)。
273
+ - **与 `embedded-template` 的关系**:**目录与 `Processer` 形态**可对齐;**具体调用的 `context` 方法与写入字段**以本门控文档为准,**禁止**整段拷贝示例脚本中与本门控无关的 compound / station / process 等逻辑。
274
+
275
+ ### 1. 从流程说明抽取
276
+
277
+ 下表各项**仅在该门控的流程说明中实际出现对应小节或规则时**才落入脚本;缺失则**不生成**该路径(或仅留 `TODO` 并在预检《优化建议》中提示文档缺口,**不得**臆造业务补全)。
278
+
279
+ | 来源 | 落点(脚本侧) |
280
+ |------|----------------|
281
+ | 门控 YAML `input` | `start` 中按 [agentic-lab-sdk.md](references/agentic-lab-sdk.md) 查询入口池 tickets(`limit`/`offset` 遵守 §2);含 `secondary` 时合并多个入口池 ID |
282
+ | 门控 YAML `output` | `complete` 中按 [agentic-lab-sdk.md](references/agentic-lab-sdk.md) 获取出口池,以 `pool.name` 与条件分支筛选目标池 |
283
+ | **化合物数据查询方式** | 按 [agentic-lab-sdk.md](references/agentic-lab-sdk.md) 调用化合物库存查询方法 |
284
+ | **字段映射表** | API 返回字段写入 `ticket.detail` 的 snake_case 键 |
285
+ | **数据处理规则**(序号表) | `start` 内计算与回填,或 `complete` 内最终路由前校验;关键分支写 `// 规则 1.x` 注释 |
286
+ | **门控脚本配置项**表 | 脚本模块级常量:`PAGE_URL`(取 `PageUrl` 值)、`DEFAULT_QUERY_LIMIT`(取入口池查询上限,缺省 `999999`)、`STATION_BASE_URL`(若有);**各门控前置处理**配置中的 `bookid` → `BOOK_ID`(每个门控独立值) |
287
+
288
+ ### 2. 分页与「查全量」(`limit` / `offset`)
289
+
290
+ 凡 [references/agentic-lab-sdk.md](references/agentic-lab-sdk.md)「可用方法一览」中标注使用 `limit` / `offset` 分页的查询方法,生成门控脚本时遵守:
291
+
292
+ 2. **流程说明写了分页**:按文档给出的 `limit`、`offset`(或等价参数名)原样写入调用。
293
+ 3. **流程说明写了「查全部/不限制条数」及具体数值**(例如明确要求 `limit: 500000`):**以流程文档为准**,不得擅自改为 `999999`。
294
+
295
+ ### 3. `start` `complete` 分工(与门控三阶段对齐)
296
+
297
+ 门控执行顺序为 **前置处理(脚本)→ 人工处理(页面)→ 后置处理(脚本)**。`start` 对应**前置处理**,`complete` 对应**后置处理**。
298
+
299
+ **代码格式与风格**须严格对齐 [references/agentic-lab-processer.md](references/agentic-lab-processer.md) 中的类型定义:
300
+
301
+ - **`start` 入参** `StartExecutionParams`:**必须**含 `valve_id`(`number`)、`pool_ids`(`number[]`);可通过 `[propName: string]: any` 扩展,但核心参数不可缺少或改名。
302
+ - **`start` 返回** `StartExecutionResult`:**必须**含 `orbit_link`(`string`)、`ticket_ids`(`number[]`)。
303
+ - **`complete` 入参** `CompleteExecutionParams`:**必须**含 `valve_id`(`number`)、`tickets`(`Record<string, any>[]`)。
304
+ - **`complete` 返回** `CompleteExecutionResult`:通过 `new_tickets`(`Record<string, any>[]`,可选)返回待写入出口池的工单,由引擎自动创建。
305
+ - **一级参数与返回值键名一律 snake_case**(如 `valve_id`、`pool_ids`、`ticket_ids`、`orbit_link`、`new_tickets`),**禁止** camelCase(如 ~~`ticketIds`~~、~~`poolIds`~~)。嵌套数据(如 `ticket.detail` 内容、SDK 方法的 `params`/`items` 等 JSON 结构)保持流程文档或 API 原有格式,不受此约束。
306
+
307
+ - **`start(params)`**(对应**前置处理**):解构 **`valve_id`、`pool_ids`**(`Processer` 入参 snake_case)→ 按 [agentic-lab-sdk.md](references/agentic-lab-sdk.md) 查询入口池数据(§2 默认大 `limit`)→ **仅当**流程说明前置处理中写明化合物查询 / 流程列表 / 工站等需求时,才按需调用对应 SDK 方法(缺则**不调**;各方法见 [agentic-lab-sdk.md](references/agentic-lab-sdk.md))→ **仅按**数据处理规则与映射更新 `ticket.detail` 中**文档涉及的键** → 按 SDK 更新 tickets(若确有写回)→ 拼装 `orbit_link`(见下方步骤)→ 返回 `{ orbit_link, ticket_ids }` 。
308
+
309
+ **`orbit_link` 生成步骤**:
310
+ 1. 从**门控脚本配置项**表提取 `PageUrl`(含 `{bookid}` 占位符),写为脚本模块级常量 `PAGE_URL`
311
+ 2. 从该门控**前置处理**配置项中提取 `bookid` 值,写为脚本模块级常量 `BOOK_ID`
312
+ 3. `start` 函数末尾拼装:`const orbit_link = PAGE_URL.replace('{bookid}', BOOK_ID)`
313
+
314
+ - **`complete(params)`**(对应**后置处理**):解构 **`valve_id`** **`tickets`**(snake_case 入参)→ **优先使用 `params.tickets` 作为业务数据源**(引擎已传入完整 ticket 数据,无需重新查询;仅当流程说明后置处理中**明确要求**获取额外数据或最新状态时才按需查询)→ 按流程说明后置处理中的规则执行业务逻辑(准备提交参数、按需调用 SDK 方法、判定成败等)→ 按 [agentic-lab-sdk.md](references/agentic-lab-sdk.md) 获取出口池 → 将入口池 tickets 更新为 `finished` → 按出口池条件映射 `new_tickets`(含 `flow_id`、`pool_id`、`order_id`、`detail`、`status: 'created'`、`parent_ticket_id`)→ 返回 `{ new_tickets }`(由引擎自动创建,**不**在脚本内直接追加 tickets)。
315
+
316
+ ### 3.1 `run` 分工(自动触发门控专用)
317
+
318
+ 自动触发门控无人工处理阶段,`run` 合并了 `start` `complete` 的职责。
319
+
320
+ - **`run(params)`**:解构 **`valve_id`、`pool_ids`**(snake_case)→ [agentic-lab-sdk.md](references/agentic-lab-sdk.md) 查询入口池数据 → 按需调用 SDK 方法 → 按数据处理规则更新 `ticket.detail` → 按 SDK 更新 tickets → 按 [agentic-lab-sdk.md](references/agentic-lab-sdk.md) 获取出口池 → 将入口池 tickets 更新为 `finished` → 按出口池条件映射 `new_tickets` → 返回 `{ new_tickets }`。
321
+
322
+ **与 `start` + `complete` 的区别**:`run` **不返回** `orbit_link` 或 `ticket_ids`(无人工阶段无需页面链接或 ticket 列表交互)。类型定义见 [references/agentic-lab-processer.md](references/agentic-lab-processer.md)。
323
+
324
+ ### 4. 运行环境约束(沙箱可用全局对象)
325
+
326
+ 门控脚本在**沙箱**中执行,**仅**以下全局对象/函数可用:
327
+
328
+ | 类别 | 可用 |
329
+ |------|------|
330
+ | 基础类型 | `Array`, `Object`, `Map`, `Set`, `JSON`, `Math`, `Date`, `Number`, `String`, `Boolean`, `RegExp` |
331
+ | 错误类型 | `Error`, `TypeError`, `ReferenceError` |
332
+ | 数值函数 | `parseInt`, `parseFloat`, `isNaN`, `isFinite` |
333
+ | 编码函数 | `encodeURIComponent`, `decodeURIComponent`, `encodeURI`, `decodeURI` |
334
+ | 异步 | `Promise`, `setTimeout`, `clearTimeout`, `setInterval`, `clearInterval` |
335
+ | 常量 | `undefined`, `NaN`, `Infinity` |
336
+ | IO | `console`(`log`/`info`/`warn`/`error`/`debug`)、`fetch`(仅限 SDK 无法覆盖的外部调用) |
337
+
338
+ **不可用**(使用即抛 `ReferenceError`):
339
+
340
+ - `URLSearchParams`、`URL`、`Headers`、`Request`、`Response`、`FormData`、`Blob`、`Buffer`
341
+ - `TextEncoder`、`TextDecoder`
342
+ - `process`、`require`、`module`、`exports`、`__dirname`、`__filename`
343
+ - `window`、`document`、`globalThis`(浏览器/Node.js 专属)
344
+
345
+ **替代方案**:
346
+
347
+ 1. **拼接 query string**——用模板字符串 + `encodeURIComponent`(不要用 `URLSearchParams`):
348
+ ```js
349
+ // 正确
350
+ const qs = `view_id=${encodeURIComponent(viewId)}&page_size=500`;
351
+ const url = `${BASE}?${qs}`;
352
+
353
+ // ❌ 错误——URLSearchParams 不存在
354
+ const qs = new URLSearchParams({ view_id: viewId, page_size: '500' });
355
+ ```
356
+
357
+ 2. **外部 HTTP 调用**——优先使用 `this.context` SDK 方法(见 [references/agentic-lab-sdk.md](references/agentic-lab-sdk.md))。仅当流程文档要求调用 SDK 未覆盖的第三方 API(如飞书/Lark)时,才使用 `fetch`;此时 URL 手动拼接,**不依赖** `URLSearchParams`。
358
+
359
+ 3. **JSON 序列化**——`JSON.stringify` / `JSON.parse` 可用(`JSON` 在沙箱白名单中)。
360
+
361
+ ### 5. 类型安全的字段访问(防止运行时 TypeError)
362
+
363
+ `ticket.detail` 的值为**任意 JSON 类型**(`string` / `number` / `boolean` / `array` / `object` / `null`)——即使 pool Schema 声明为 `text`,运行时也可能收到 `number` 或 `null`。**生成代码时须遵守**:
364
+
365
+ 1. **禁止直接对 `detail` 值调用 `.trim()` / `.split()` / `.toLowerCase()` 等 `String.prototype` 方法**——若该值为 `number` 或 `null`,会抛出 `TypeError: xxx.trim is not a function`。
366
+ 2. **字符串读取**:先用 `String()` 转换或 `typeof` 判断:
367
+ ```js
368
+ // ✅ 正确
369
+ const barcode = String(detail.source_barcode ?? '');
370
+ // ✅ 正确
371
+ const barcode = detail.source_barcode != null ? String(detail.source_barcode) : '';
372
+ // ❌ 错误——detail.source_barcode 可能为 number / null
373
+ const barcode = detail.source_barcode.trim();
374
+ ```
375
+ 3. **数字读取**:先用 `Number()` 转换并检查 `Number.isFinite()`:
376
+ ```js
377
+ const amount = Number(detail.error_tolerance_mg);
378
+ if (!Number.isFinite(amount)) { /* fallback */ }
379
+ ```
380
+ 4. **数组 / 对象读取**:先用 `Array.isArray()` `typeof === 'object'` 检查后再操作。
381
+ 5. 若脚本内多处需要安全取值,可在模块级定义简短辅助函数(见 [embedded-template/scripts/示例数据与校验门控.js](embedded-template/scripts/示例数据与校验门控.js) 中的 `str()` / `num()`),减少重复模式。
382
+
383
+ ### 6. 参考代码(按优先序打开)
384
+
385
+ 1. [references/agentic-lab-processer.md](references/agentic-lab-processer.md)(**`Processer` 类型定义与代码风格**参考;`start`/`complete` 输入输出类型、snake_case 命名)
386
+ 2. [embedded-template/scripts/示例数据与校验门控.js](embedded-template/scripts/示例数据与校验门控.js)(**结构与分页约定**参考;SDK 方法**仅当本门控文档需要时**才纳入生成,勿默认照抄示例中的全部调用;**列表类查询默认 `limit: 999999`**)
387
+ 3. [references/agentic-lab-sdk.md](references/agentic-lab-sdk.md)
388
+ 4. 多门控流程:按拓扑为每个门控各写一对 `valves/<基名>.md` 与 `scripts/<基名>.js`,API 与分页约定同上;勿使用 `agentic-lab-sdk.md` 未列出的 `context` 成员。
389
+
390
+ ### 7. 产物版本追踪
391
+
392
+ 每次生成或修改流程注册包时,**必须**在产物中维护版本信息,帮助用户识别产物来源和版本。
393
+
394
+ #### 7.1 SKILL.md frontmatter 版本
395
+
396
+ 生成的流程注册包 `SKILL.md` frontmatter **必须**包含 `metadata` 块:
397
+
398
+ ```yaml
399
+ ---
400
+ name: <与根目录同名-kebab-case>
401
+ description: <≤1024 字符>
402
+ metadata:
403
+ version: "<semver>"
404
+ generated_by: lab-flow-designer
405
+ generated_at: "<YYYY-MM-DD>"
406
+ ---
407
+ ```
408
+
409
+ - **初次生成**:`version: "1.0.0"`,`generated_at` 为当天日期。
410
+ - **迭代修改**:读取现有 `metadata.version`,按变更范围递增(patch:修复;minor:新增逻辑;major:输入输出结构变更),更新 `generated_at`。
411
+
412
+ #### 7.2 脚本版本常量
413
+
414
+ 每个 `scripts/<基名>.js` 在 doc comment 之后、`DEFAULT_QUERY_LIMIT` 等业务常量之前,**必须**包含:
415
+
416
+ ```javascript
417
+ // --- Artifact Version ---
418
+ const __ARTIFACT_VERSION__ = '<与 SKILL.md metadata.version 一致>';
419
+ const __ARTIFACT_SKILL__ = 'lab-flow-designer';
420
+ ```
421
+
422
+ 迭代修改时同步更新 `__ARTIFACT_VERSION__` 值。
423
+
424
+ #### 7.3 构造函数版本打印
425
+
426
+ `Processer` `constructor` 中,`this.context = context;` 之后**必须**添加:
427
+
428
+ ```javascript
429
+ console.info(`[Processer] v${__ARTIFACT_VERSION__} (skill: ${__ARTIFACT_SKILL__})`);
430
+ ```
431
+
432
+ ## Gotchas
433
+
434
+ 生成前快速检查清单(规则详见对应章节,此处仅提醒要点):
435
+
436
+ - 合规预检仅「初次生成」时执行(见「会话模式判定」)
437
+ - 列表查询默认 `limit: 999999`;门控脚本配置项有自定义上限时从其取(见「编写指引 §2」)
438
+ - Pool Schema 须含六列(字段/字段标题/字段描述/字段类型/属性/默认值),字段列为 snake_case(见「生成流程 §4」)
439
+ - 池文件名与数据池表「显示名称」逐字一致(见「生成流程 §2」)
440
+ - Mermaid = 矩形 `[…]`、门控 = 六边形 `{{…}}`(见「生成流程 §3.4」)
441
+ - 合流门控 `pool_ids` 须覆盖所有入口池(见「编写指引 §1」)
442
+ - `context` 仅使用 [agentic-lab-sdk.md](references/agentic-lab-sdk.md) 已列方法,禁止虚构 API
443
+ - start/complete 输入输出严格对齐 [agentic-lab-processer.md](references/agentic-lab-processer.md)(见「编写指引 §3」)
444
+ - 一级参数/返回值 snake_case;嵌套 JSON 保持原格式(见「编写指引 §3」)
445
+ - `orbit_link` = `PageUrl` + `bookid`(见「编写指引 §3 orbit_link 生成步骤」)
446
+ - 门控三阶段:前置处理 → `start`、后置处理 → `complete`、人工处理 → UI 技能(见「解析流程说明 §1」)
447
+ - **触发方式**:自动触发门控脚本须实现 `run`(非 `start` + `complete`);人工触发保持 `start` + `complete`(见「编写指引 §3.1」与 [agentic-lab-processer.md](references/agentic-lab-processer.md))
448
+ - **模型引用**:流程说明中关联 3D 模型的池和门控,须在对应 `pools/*.md` 或 `valves/*.md` 写入 `## 模型引用`(模型名称 + 版本);无模型引用时省略
449
+ - `complete` 优先使用 `params.tickets`,非必要不重查(见「编写指引 §3」)
450
+ - 脚本以 `Processer` 类结束,禁止 `return`/`module.exports`/`export`(见「生成流程 §6」)
451
+ - 按需生成,禁止冗余:代码和 Schema 仅覆盖流程文档明确写出的内容(见「编写指引 §0」)
452
+ - **类型安全**:禁止直接对 `ticket.detail` 值调用 `.trim()` / `.split()` 等字符串方法;必须先 `String()` 转换或 `typeof` 判断(见「编写指引 §5」)
453
+ - **运行环境**:门控脚本在沙箱执行,`URLSearchParams`/`URL`/`Buffer` Web/Node API **不可用**;拼接 query string 须用模板字符串 + `encodeURIComponent`(见「编写指引 §4」)
454
+ - **外部 HTTP**:优先用 `this.context` SDK 方法;仅 SDK 未覆盖的第三方 API 才用 `fetch`,URL 手动拼接(见「编写指引 §4」)
455
+ - **产物版本**:SKILL.md frontmatter 须含 `metadata.version`;每个脚本须含 `__ARTIFACT_VERSION__` / `__ARTIFACT_SKILL__` 常量及 constructor `console.info`(见「编写指引 §7」)
456
+ - **脚本自测**:凡写入或修改 `scripts/*.js`,必须用 `testing/test-processer.mjs` 执行自测并自动修复,直到正常轮全 `pass`(见「脚本自测」)
457
+
458
+ ## 扩展
459
+
460
+ 若一份说明含多条独立流水线,应对每条线各建一个输出目录与独立 `SKILL.md`(各自 `name`),勿混在同一包内。
461
+
462
+ ## 验证生成结果
463
+
464
+ 对**生成目录**(输出目录,即当前工作目录或用户指定的路径)逐项自检;下列**对照物均为本 skill 内路径**。
465
+
466
+ **流程来源**:若该包为 **初次生成** 产物,源流程文档应已通过 **「流程文档合规预检」**;复查可对照 [references/业务流程文档标准.md](references/业务流程文档标准.md) §4。**迭代修改**路径无此强制要求。
467
+ **结构清单**:根目录 `SKILL.md`(合法 `name`/`description`、固定二级标题:`概述`、`核心概念`、`流程图`、`节点清单`、`门控执行规范`、`使用方式`)、`**连接关系:**`、`### Pool 节点` / `### Valve 节点`、`Processer` 类与门控执行规范代码块、存在 `pools/` / `valves/` / `scripts/`、`valves` 与 `scripts` 同名成对、任取一个 `pools/*.md` 的 Schema 表头含 **字段** / **字段标题** / **属性** 且数据行「字段」列为 snake_case。
468
+
469
+ **版本追踪**:`SKILL.md` frontmatter 含 `metadata.version` / `metadata.generated_by` / `metadata.generated_at`;每个 `scripts/*.js` 含 `__ARTIFACT_VERSION__` 常量(值与 `metadata.version` 一致)和 `__ARTIFACT_SKILL__` 常量;`Processer` constructor 含 `console.info` 版本打印。
470
+
471
+ **对照物**:[embedded-template/](embedded-template/)(已知良好缩小范例)、[references/skill-package-layout.md](references/skill-package-layout.md)、[references/agentic-lab-sdk.md](references/agentic-lab-sdk.md)。
472
+
473
+ **说明**:若工作区根目录另有自动化校验 Shell,可自行对生成包运行;具体脚本名与参数以工作区为准,**不**写入本 skill 必读引用。内置 [`embedded-template/SKILL.md`](embedded-template/SKILL.md) 的 `name` 可与目录名 `embedded-template` **故意不一致**(仅示意)。
474
+
475
+ ## 脚本自测(生成后必须执行)
476
+
477
+ **适用**:**初次生成** 与 **迭代修改** 两种模式下,凡写入或修改了 `scripts/*.js`,都**必须**对涉及的脚本执行自测。全部正常轮 `pass` 后方可交付用户。
478
+
479
+ ### 自测工具
480
+
481
+ skill 内置测试工具 [`testing/test-processer.mjs`](testing/test-processer.mjs),零外部依赖,直接通过 `node` 执行。
482
+
483
+ ### 执行命令
484
+
485
+ 对每个生成或修改的 `scripts/<基名>.js` 执行:
486
+
487
+ ```bash
488
+ node <本skill目录>/testing/test-processer.mjs \
489
+ --script <输出目录>/scripts/<基名>.js \
490
+ --pools-dir <输出目录>/pools \
491
+ --valves-dir <输出目录>/valves \
492
+ --valve-name <基名>
493
+ ```
494
+
495
+ ### 验证范围
496
+
497
+ 工具分两轮 mock 执行,分开报告:
498
+
499
+ | 轮次 | 检查内容 | 失败级别 |
500
+ |------|---------|---------|
501
+ | **语法检查** | JavaScript 语法正确性 | 阻断 |
502
+ | **结构检查** | `Processer` 类存在,含 `constructor` + (`start`、`complete`)(人工触发)或 `run`(自动触发) | 阻断 |
503
+ | **正常轮 `start`** | 人工触发:正常类型 mock 数据运行,检查返回 `{ orbit_link: string, ticket_ids: number[] }` | 阻断 |
504
+ | **正常轮 `complete`** | 人工触发:正常类型 mock 数据运行,检查返回 `{ new_tickets: [...] }` 结构正确 | 阻断 |
505
+ | **正常轮 `run`** | 自动触发:正常类型 mock 数据运行,检查返回 `{ new_tickets: [...] }` 结构正确 | 阻断 |
506
+ | **对抗轮 `start` + `complete` / `run`** | 第 3 条 ticket 的 text 字段填为 number/null,验证类型安全编码 | 警告(不阻断) |
507
+ | **合规审计** | SDK 方法白名单、列表查询 `limit`/`offset`、返回值 snake_case | 未知 SDK 方法→阻断;其余→警告 |
508
+
509
+ ### 结果判定与自动修复
510
+
511
+ 工具输出 JSON,`status` 为 `pass` 或 `fail`。
512
+
513
+ **自动修复循环(最多 3 轮):**
514
+
515
+ 1. 运行测试,读取输出 JSON
516
+ 2. 若**正常轮有 `fail`**:
517
+ a. 读取 `errors` 数组中的错误描述
518
+ b. 对照下方「修复指引表」,在脚本中定位并修复问题
519
+ c. 修复后**立即重新运行测试**
520
+ d. 重复直到正常轮全部 `pass`(最多 3 轮)
521
+ 3. 若**对抗轮有 `fail`**:
522
+ a. 读取 `warnings`,检查是否为真实的类型安全隐患
523
+ b. 若是:按「编写指引 §5」添加 `String()` / `Number()` 防御
524
+ c. 若为误报(该字段在真实数据中不可能为 null/number):忽略
525
+ 4. **3 轮后仍有正常轮 `fail`**:停止修复,向用户报告剩余问题及已尝试的修复
526
+ 5. 所有正常轮 `pass` 后:向用户报告测试结果摘要(含对抗轮警告,如有)
527
+
528
+ ### 修复指引表
529
+
530
+ | 错误类型 | 错误示例 | 自动修复策略 |
531
+ |---------|---------|------------|
532
+ | `SyntaxError` | `Unexpected token` | 检查脚本语法,修正括号/引号/关键字错误 |
533
+ | `TypeError: x.trim is not a function` | detail 值非字符串直接调 `.trim()` | 替换为 `String(x ?? '').trim()` 或用 `str()` 辅助函数 |
534
+ | `TypeError: Cannot read properties of null` | 未做 null 检查 | 添加可选链 `?.` 或空值合并 `??` |
535
+ | `start() 返回值缺 orbit_link` | `orbit_link must be string, got undefined` | 检查 `start` 返回语句,补全 `orbit_link` 字段 |
536
+ | `start() 返回值缺 ticket_ids` | `ticket_ids must be array, got undefined` | 确保返回 `ticket_ids: tickets.map(t => t.id)` |
537
+ | `complete() new_tickets 缺必填字段` | `new_tickets[0].pool_id must be number` | 检查 new_tickets 映射逻辑,补全 `flow_id`/`pool_id`/`order_id`/`detail`/`status` |
538
+ | `Unknown SDK namespace/method` | `Unknown SDK method called: context.xxx.yyy` | 替换为 [agentic-lab-sdk.md](references/agentic-lab-sdk.md) 中已有的方法 |
539
+ | `ticket.list called without limit` | `ticket.list called without explicit limit` | 添加 `limit: DEFAULT_QUERY_LIMIT, offset: 0` |
540
+ | `camelCase key in return value` | `"ticketIds" is camelCase — must be snake_case` | 改为 `ticket_ids` 等 snake_case 键名 |
541
+ | `Processer missing start() method` | 结构检查未通过 | 确保 `Processer` 类包含 `async start(params)` 方法 |
542
+ | `Processer missing run() method` | 自动触发门控结构检查未通过 | 确保 `Processer` 类包含 `async run(params)` 方法,移除 `start`/`complete` |
543
+ | `run() new_tickets 缺必填字段` | `new_tickets[0].pool_id must be number` | 检查 run 中 new_tickets 映射逻辑,补全 `flow_id`/`pool_id`/`order_id`/`detail`/`status` |
544
+
545
+ ## 脚本预览(试运行)
546
+
547
+ **定位**:自测验证脚本"对不对"(语法、结构、契约),预览验证脚本"做了什么"(SDK 调用链、数据变换、路由逻辑)——两者互补。自测必须先 `pass`,预览才有意义。预览结果不影响 `pass/fail` 判定。
548
+
549
+ ### 何时使用
550
+
551
+ - **初次生成后**:自测全部通过后,自动执行一次预览,将报告展示给用户确认
552
+ - **用户提供样本数据时**:使用 `--data` 模式,用真实或半真实数据验证具体业务场景
553
+ - **迭代修改脚本逻辑后**:重新预览确认变更效果
554
+
555
+ ### 执行命令
556
+
557
+ **自动生成数据**(从 pool schema 生成 5 条场景 tickets):
558
+
559
+ ```bash
560
+ node <本skill目录>/testing/test-processer.mjs \
561
+ --preview \
562
+ --script <输出目录>/scripts/<基名>.js \
563
+ --pools-dir <输出目录>/pools \
564
+ --valves-dir <输出目录>/valves \
565
+ --valve-name <基名>
566
+ ```
567
+
568
+ **用户提供样本数据**:
569
+
570
+ ```bash
571
+ node <本skill目录>/testing/test-processer.mjs \
572
+ --preview \
573
+ --data <样本数据.json> \
574
+ --script <输出目录>/scripts/<基名>.js \
575
+ --pools-dir <输出目录>/pools \
576
+ --valves-dir <输出目录>/valves \
577
+ --valve-name <基名>
578
+ ```
579
+
580
+ ### 样本数据格式
581
+
582
+ 用户只需提供 `detail` 对象,工具自动补全 `id`/`flow_id`/`pool_id`/`order_id`/`status`/`uuid`:
583
+
584
+ ```json
585
+ {
586
+ "tickets": [
587
+ { "detail": { "cmpd_id": "CA1078", "cas": "28022-43-7", "amount": 50 } },
588
+ { "detail": { "cmpd_id": "CA1079", "cas": "12345-67-8", "amount": 120 } }
589
+ ]
590
+ }
591
+ ```
592
+
593
+ ### 场景数据生成指引
594
+
595
+ 当用户未提供 `--data` 时,工具从 pool schema 自动生成场景 tickets。若 pool schema 字段较少(如仅 `id` + `detail`),自动生成的 tickets 可能无业务字段,导致脚本中依赖特定字段的分支不被触发。此时 agent 应:
596
+
597
+ 1. 阅读门控的 `valves/<基名>.md` 中的「数据处理规则」
598
+ 2. 提取脚本依赖的关键字段(如 `cmpd_id`、`process_ids`、`amount` 等)
599
+ 3. 生成一份 `--data` JSON,字段值覆盖主要业务路径
600
+ 4. 用 `--data` 模式重新预览,确认完整数据流
601
+
602
+ ### 报告解读
603
+
604
+ 预览报告包含以下关键信息,agent 应逐项核对:
605
+
606
+ | 报告区域 | 关注点 |
607
+ |----------|--------|
608
+ | **SDK 调用链** | 调用顺序是否与流程文档描述一致;参数是否正确(如 `filter` 中的字段名、`limit` 值) |
609
+ | **ticket.detail 变更** | 变更的字段是否与流程文档「数据处理规则」吻合;是否有意外的字段被覆盖 |
610
+ | **start() 返回值** | `orbit_link` 格式正确;`ticket_ids` 包含所有处理的 tickets |
611
+ | **数据路由** | tickets 是否按预期分流到对应出口池;池名、数量、status 是否正确 |
612
+ | **执行摘要** | 确认 start/complete 均成功;检查「未调用的 SDK 方法」是否符合预期 |