@alipay/alipay-aipay 1.6.7-beta2 → 1.6.7

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alipay/alipay-aipay",
3
- "version": "1.6.7-beta2",
3
+ "version": "1.6.7",
4
4
  "description": "支付宝 AI 付接入 Skill 安装包 - 优先安装 Agent Skill,并在 macOS/Linux 后台准备用户级 CLI 工具",
5
5
  "type": "module",
6
6
  "bin": {
package/skill/VERSION CHANGED
@@ -1 +1 @@
1
- 1.6.7-beta2
1
+ 1.6.7
@@ -25,7 +25,7 @@
25
25
 
26
26
  ### 耗时事件规则
27
27
 
28
- `start-run` 已确定 `run_id`;stage 由登记动作异步记录,Agent 不手工上报。遥测失败不改变业务;诊断只按需读 `../normal/telemetry.md`。
28
+ `start-run` 已确定 `RUN_ID`;stage 由登记动作在前台固定 event/c4 并执行最长 3 秒的同步上传,Agent 不重复手工上报。每个会生成 stage 的命令前回顾当前可见用户消息得到 `HISTORY_COUNT`,并传入下文登记的两个 gateway 内部参数;无法可靠回顾时用 `null`。遥测失败不改变业务、卡点或对客交付;诊断只按需读 `../normal/telemetry.md`。
29
29
 
30
30
  ### 服务声明执行护栏
31
31
 
@@ -151,7 +151,7 @@ node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" integration-message loc
151
151
  3. Unix/macOS/Linux 从本 flow 所在的 `references/integration/` 目录执行唯一准备入口:
152
152
 
153
153
  ```bash
154
- node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" sandbox ensure "<规范化项目路径>" "<已确认服务端语言>"
154
+ node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" sandbox ensure "<规范化项目路径>" "<已确认服务端语言>" [--telemetry-run-id "$RUN_ID" --telemetry-history-count "$HISTORY_COUNT"]
155
155
  ```
156
156
 
157
157
  4. Windows 不调用快速沙箱脚本。普通代码开发或完整接入请求没有明确要求当前配置沙箱时,不展示申领消息、不补问,直接记录 `sandboxConfigState=VERIFY_PENDING` 并继续步骤 2。只有用户明确要求现在配置/恢复 Windows 沙箱时,才执行下列既有标准消息 `sandbox.windows.manual_setup`;该消息使用自由资料回复,不要求用户输入 `1` 或自行执行脚本。随后只处理用户针对本轮该消息提供的资料:完整有效时写入目标项目的受保护本机配置并记录 `READY`,部分或错误时使用既有受控失败分支补问实际缺失/错误字段:
@@ -201,6 +201,8 @@ node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" integration-message win
201
201
  node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" integration-message start-confirm --root-intent "$ROOT_INTENT" --product-type "$PRODUCT_TYPE" --product-name "$PRODUCT_NAME" --project-path "$PROJECT_PATH" --project-selection "$PROJECT_SELECTION" --language "$SERVER_LANGUAGE" --framework "$FRAMEWORK" --framework-source "$FRAMEWORK_SOURCE"
202
202
  ```
203
203
 
204
+ 若 bootstrap 尚未创建正式 run,本命令在任何 Integration 业务 stage 前原子创建 run 和 `clarify_intent`,并输出后续唯一使用的 `RUN_ID` marker;触发本命令的首条消息不计入新 run。已有同组合 active run 时只复用 marker。步骤 3 之后所有能生成 stage 的登记命令都必须携带当前 telemetry context;runner 已生成 stage 后 Agent 禁止重复调用 `telemetry stage`。
205
+
204
206
  runner 失败时不得展示手写方案或进入步骤 3。成功时必须取得唯一 `ALIPAY_AIPAY_INTERNAL:CUSTOMER_MESSAGE_DELIVERY_REQUIRED=integration.start.confirm`;缺失或重复都视为失败。stdout 是步骤 2 唯一对客消息;命令后的下一个动作必须把 stdout 作为可见进行中消息原文送达,不得作为最终答复结束当前回合,送达前禁止调用工具。命令面板、折叠输出、内部思考或“已渲染/已展示”说明都不能替代交付;禁止添加 `<...>` 标签、“已输出完整方案”“服务声明已打印”、重复摘要或任何前后缀。送达后同一回合立即执行 `node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" flow integration development --product-type "$PRODUCT_TYPE"`,不得总结、询问、等待回复、解码内部值或再次渲染方案。
205
207
 
206
208
  - `full_process`:`../normal/full-process-routing.md` 已用同一方案绑定检查器事实、产品、项目、语言/框架和服务声明;送达后按该路由选择唯一 Integration Worker 或当前 Agent 执行,禁止重显或确认。两者都须完成本 flow 全部适用接口、条件和 checklist。用户中断后事实变化则返回 router 重新澄清、扫描和展示。方案仍禁止提前展示 MCC、授权范围、开通材料或 onboarding 待办。
@@ -237,7 +239,7 @@ runner 失败时不得展示手写方案或进入步骤 3。成功时必须取
237
239
  4. Unix/macOS/Linux 仅在 `sandboxConfigState=READY` 时执行以下唯一复核命令,不先检查文件、不读取字段、不运行其他诊断:
238
240
 
239
241
  ```bash
240
- node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" sandbox reverify "<规范化项目路径>" "<已确认服务端语言>"
242
+ node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" sandbox reverify "<规范化项目路径>" "<已确认服务端语言>" --telemetry-run-id "$RUN_ID" --telemetry-history-count "$HISTORY_COUNT"
241
243
  ```
242
244
 
243
245
  5. `reverify` 只接受与步骤 1 相同的三个互斥终态。`READY` 更新 `sandboxConfigState=READY` 并立即进入步骤 4;`VERIFY_PENDING` 已由脚本输出唯一待配置正文,更新状态后立即进入步骤 4。`reverify` 不允许创建分支,若异常出现 `CREATED|CREATE_PENDING` 标记必须按协议失败停止。所有终态之后禁止追加任何 `jq`、`cat`、`grep`、`ls`、`stat` 或临时脚本。
@@ -337,7 +339,7 @@ node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" sandbox summary "<produ
337
339
  Windows 从项目实际读取的同一本机配置构造不含密码和密钥原文的 `ENVIRONMENT_ROWS`,再从本 flow 所在目录执行以下固定命令;不得重新索取或复述步骤 1 已提供的敏感值,也不得改用 Unix 快速沙箱脚本:
338
340
 
339
341
  ```powershell
340
- node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" integration-message windows-sandbox-summary --product-name "$PRODUCT_NAME" --config-path "$CONFIG_PATH" --environment-rows "$ENVIRONMENT_ROWS"
342
+ node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" integration-message windows-sandbox-summary --product-name "$PRODUCT_NAME" --config-path "$CONFIG_PATH" --environment-rows "$ENVIRONMENT_ROWS" --telemetry-run-id "$RUN_ID" --telemetry-history-count "$HISTORY_COUNT"
341
343
  ```
342
344
 
343
345
  Windows 的 `CONFIG_PATH` 必须是步骤 1/3 已校验的实际本机配置绝对路径;`ENVIRONMENT_ROWS` 只包含实际取得的非敏感应用、商家、买家和沙箱标识,缺失可选项直接省略。两个 renderer 任一失败都按摘要展示失败处理,禁止手写补齐。
@@ -556,21 +558,21 @@ node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" integration-message saf
556
558
 
557
559
  <!-- ALIPAY_AIPAY_PRODUCT:aipay:START -->
558
560
  ```bash
559
- node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" integration-message checklist-result --variant AIPAY --project-path "$PROJECT_PATH" --scope-receipt "$CHECKLIST_SCOPE_RECEIPT" --overall-result "$OVERALL_RESULT" --failed-items "$FAILED_ITEMS" --manual-items "$MANUAL_ITEMS" --sandbox-result "$SANDBOX_RESULT" --sandbox-config-state "$SANDBOX_CONFIG_STATE" --blocking-defect-state "$BLOCKING_DEFECT_STATE" --execution-mode "$EXECUTION_MODE" --next-flow-reminder "$NEXT_FLOW_REMINDER"
561
+ node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" integration-message checklist-result --variant AIPAY --project-path "$PROJECT_PATH" --scope-receipt "$CHECKLIST_SCOPE_RECEIPT" --overall-result "$OVERALL_RESULT" --failed-items "$FAILED_ITEMS" --manual-items "$MANUAL_ITEMS" --sandbox-result "$SANDBOX_RESULT" --sandbox-config-state "$SANDBOX_CONFIG_STATE" --blocking-defect-state "$BLOCKING_DEFECT_STATE" --execution-mode "$EXECUTION_MODE" --next-flow-reminder "$NEXT_FLOW_REMINDER" --telemetry-run-id "$RUN_ID" --telemetry-history-count "$HISTORY_COUNT"
560
562
  ```
561
563
  <!-- ALIPAY_AIPAY_PRODUCT:END -->
562
564
  <!-- ALIPAY_AIPAY_PRODUCT:webpay:START -->
563
565
  ```bash
564
- node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" integration-message checklist-result --variant WEBPAY --project-path "$PROJECT_PATH" --scope-receipt "$CHECKLIST_SCOPE_RECEIPT" --overall-result "$OVERALL_RESULT" --failed-items "$FAILED_ITEMS" --manual-items "$MANUAL_ITEMS" --webpay-experience-result "$WEBPAY_EXPERIENCE_RESULT" --sandbox-config-state "$SANDBOX_CONFIG_STATE" --blocking-defect-state "$BLOCKING_DEFECT_STATE" --execution-mode "$EXECUTION_MODE" --next-flow-reminder "$NEXT_FLOW_REMINDER"
566
+ node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" integration-message checklist-result --variant WEBPAY --project-path "$PROJECT_PATH" --scope-receipt "$CHECKLIST_SCOPE_RECEIPT" --overall-result "$OVERALL_RESULT" --failed-items "$FAILED_ITEMS" --manual-items "$MANUAL_ITEMS" --webpay-experience-result "$WEBPAY_EXPERIENCE_RESULT" --sandbox-config-state "$SANDBOX_CONFIG_STATE" --blocking-defect-state "$BLOCKING_DEFECT_STATE" --execution-mode "$EXECUTION_MODE" --next-flow-reminder "$NEXT_FLOW_REMINDER" --telemetry-run-id "$RUN_ID" --telemetry-history-count "$HISTORY_COUNT"
565
567
  ```
566
568
  <!-- ALIPAY_AIPAY_PRODUCT:END -->
567
569
  <!-- ALIPAY_AIPAY_PRODUCT:apppay:START -->
568
570
  ```bash
569
- node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" integration-message checklist-result --variant APPPAY --project-path "$PROJECT_PATH" --scope-receipt "$CHECKLIST_SCOPE_RECEIPT" --overall-result "$OVERALL_RESULT" --failed-items "$FAILED_ITEMS" --manual-items "$MANUAL_ITEMS" --sandbox-config-state "$SANDBOX_CONFIG_STATE" --blocking-defect-state "$BLOCKING_DEFECT_STATE" --execution-mode "$EXECUTION_MODE" --next-flow-reminder "$NEXT_FLOW_REMINDER"
571
+ node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" integration-message checklist-result --variant APPPAY --project-path "$PROJECT_PATH" --scope-receipt "$CHECKLIST_SCOPE_RECEIPT" --overall-result "$OVERALL_RESULT" --failed-items "$FAILED_ITEMS" --manual-items "$MANUAL_ITEMS" --sandbox-config-state "$SANDBOX_CONFIG_STATE" --blocking-defect-state "$BLOCKING_DEFECT_STATE" --execution-mode "$EXECUTION_MODE" --next-flow-reminder "$NEXT_FLOW_REMINDER" --telemetry-run-id "$RUN_ID" --telemetry-history-count "$HISTORY_COUNT"
570
572
  ```
571
573
  <!-- ALIPAY_AIPAY_PRODUCT:END -->
572
574
 
573
- 用户输入计数只统计 `clarify_intent` 之后、当前 active run 内 Agent 收到的每条聊天框用户消息,不按是否与 Skill 相关筛选。Agent 必须在任何解释、分类、路由、runner 或回复前执行 `node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" telemetry count-user-input --input-id "$USER_INPUT_ID"`;登记 runner 的输入参数只作同一消息的幂等兜底。只有本地计数状态不可用且已重新核对时,才在 checklist 命令末尾追加 `--user-input-after-clarify-intent <count>`;runner 会拒绝明显不合理计数。
575
+ 用户输入计数严格继承 `runtime-entry.md`:active run 内每条聊天框用户消息先执行唯一 `count-user-input --run-id "$RUN_ID" --input-id "$USER_INPUT_ID"`,不按 Skill 相关性筛选;runner、renderer 和 checklist 不做隐式计数。checklist 生成 `integration.complete_coding` 和 `integration_summary` 前使用同一个 `HISTORY_COUNT` 快照,正式值始终由 runtime counter 写入,禁止传入或覆盖 `user_input_after_clarify_intent`。
574
576
 
575
577
  同一次代码开发流程只渲染一次最终 checklist 结果;renderer stdout 是本次默认收口的唯一对客正文,禁止在前后追加风险说明、通过项摘要、执行说明、衔接提醒或第二份待办。
576
578
 
@@ -40,7 +40,7 @@ alipay-cli mcp call alipay-anonymous-sandbox.createAnonymousSandbox \
40
40
  | 变量 | 来源 | 取值规则 |
41
41
  |------|------|----------|
42
42
  | `PLATFORM` | AI 编程工具识别结果 | 参考通用脚本 `../../../normal/scripts/detect_dev_tool.sh` 识别当前工具后使用其输出值;缺失时使用 `unknown`。例如 Codex 环境检测结果为 `codex` |
43
- | `PLATFORM_ID` | 当前流程 `run_id` | 由 `sandbox_config.sh` 通过 `common.sh` 从当前流程 run context 读取,遥测开启或关闭都不影响该值;若宿主提供 `COZE_PROJECT_ID`、`MEOO_PROJECT_ID`,或 `MIAODA` 环境下的 `VITE_APP_ID`/`PLATFORM_ID`,新建 run 时优先以该项目 ID 为 `run_id`;缺失时不阻断沙箱创建 |
43
+ | `PLATFORM_ID` | 第三方项目 ID;缺失时为当前逻辑 `run_id` | 由 `sandbox_config.sh` 通过 `common.sh` 读取,遥测开启或关闭都不影响该值;第三方项目 ID 只用于项目维度,不能生成逻辑 `run_id`,缺失时才保持 `PLATFORM_ID <- run_id` fallback,且不阻断沙箱创建 |
44
44
  | `ALIPAYCLI_BIZ_INFO` | 当前生效 Skill 的 `VERSION` 与匿名机器哈希 | 由 `common.sh` 动态生成 JSON:`{"skill":"alipay-aipay","skill_version":"v<当前 VERSION>","skill_user_id":"machine_<32位匿名机器哈希>"}`;`skill` 固定,版本统一带 `v` 前缀,`skill_user_id` 复用 telemetry 的 `machineUserID`,极端环境无法取得合法 `machine_` 标识时省略该字段;禁止由 Agent 手写或沿用外部同名值 |
45
45
  | `PRODUCT` | 不再传入 | 该 MCP 方法当前不需要产品上下文;不得把产品名写入 `--data` 或 CLI 环境变量 |
46
46
 
@@ -121,7 +121,7 @@ if [ "$MODE" = "ensure" ] || [ "$MODE" = "reverify" ]; then
121
121
  emit_control_field "SANDBOX_ENSURE_ACTION" "$ENSURE_ACTION" || exit 1
122
122
  emit_control_field "SANDBOX_CONFIG_PATH" "$CONFIG_PATH" || exit 1
123
123
  emit_control "FLOW:SANDBOX_CONFIG_READY"
124
- emit_stage_metric_async "integration.create_sandbox"
124
+ emit_stage_metric "integration.create_sandbox"
125
125
  exit 0
126
126
  fi
127
127
 
@@ -328,4 +328,4 @@ fi
328
328
 
329
329
  emit_control_field "SANDBOX_CONFIG_PATH" "$CONFIG_PATH" || exit 1
330
330
  emit_control "FLOW:SANDBOX_CONFIG_READY"
331
- emit_stage_metric_async "integration.create_sandbox"
331
+ emit_stage_metric "integration.create_sandbox"
@@ -6,6 +6,8 @@
6
6
 
7
7
  其他 Skill 相对命令以 `references/normal/` 为 workdir。`PROJECT_INPUT` 保留原话;Agent 确定两类项目的真实 `PROJECT_PATH`,以 `--project-path` 交 runner 校验。复用须选定项目根,位置未知先定位候选;“当前目录”仅在 runner 识别为项目根时接受。后续只用规范化绝对路径。
8
8
 
9
+ `full_process` 的 `RUN_ID` 只取 `runtime-entry.md` 中 `start-run` 的唯一 marker。active run 期间每条聊天框用户消息都先执行统一 `count-user-input --run-id "$RUN_ID"`,与 Skill 无关的插话和中断后输入也不例外。每个登记 stage 动作前回顾当前可见用户历史得到 `HISTORY_COUNT`,无法可靠回顾时为 `null`;能生成 stage 的 runtime 命令按对应 flow 追加 `--telemetry-run-id "$RUN_ID" --telemetry-history-count "$HISTORY_COUNT"`。Integration Worker 只接收这两个低敏 telemetry 上下文字段并透传给原 flow;正式计数仍由 runtime state 读取。`integration_summary` 不关闭 full-process run,只有 `all_summary` 关闭;telemetry 不改变本文件的业务衔接和卡点。
10
+
9
11
  ## 边界
10
12
 
11
13
  - 只编排 Integration 与 Onboarding,不复制其状态、完成条件和红线。完整接入复用 Integration 步骤 2 的唯一非阻塞 `integration.start.confirm`、同一检查器事实和模板,本轮只渲染一次。
@@ -76,7 +78,7 @@ node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" integration-message sta
76
78
 
77
79
  上面命令失败时不得展示手写确认或进入子流程。成功时必须取得唯一 `ALIPAY_AIPAY_INTERNAL:CUSTOMER_MESSAGE_DELIVERY_REQUIRED=integration.start.confirm`;缺失或重复视为失败。参数必须是当前确定值,禁止直接拼用户输入。runner 校验产品 variant 并固定服务声明;实际范围仍取当前 Integration flow 和 checklist。
78
80
 
79
- 交接事实必须来自 runner 内同一次 `scan`,不得用描述、自报或历史分类代替;`evidence` 不进 renderer,Onboarding 前不传/猜 `mccCode`。方案 stdout 按 marker 送达后执行 `node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" flow integration development --product-type "$PRODUCT_TYPE"`;支持 Worker 的宿主由唯一 Worker 完成步骤 3 至步骤 8,不支持 Worker 的宿主仍由当前 Agent 串行完成步骤 3 至步骤 8。loader 仍记录兼容 stage 和预开发阅读 stage;禁止手工 telemetry、解码内部值、重复扫描或重显方案。
81
+ 交接事实必须来自 runner 内同一次 `scan`,不得用描述、自报或历史分类代替;`evidence` 不进 renderer,Onboarding 前不传/猜 `mccCode`。方案 stdout 按 marker 送达后执行 `node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" flow integration development --product-type "$PRODUCT_TYPE"`;支持 Worker 的宿主由唯一 Worker 完成步骤 3 至步骤 8,不支持 Worker 的宿主仍由当前 Agent 串行完成步骤 3 至步骤 8。loader 只加载当前分支规则;业务完成后由登记入口记录完成态 stage。禁止手工 telemetry、解码内部值、重复扫描或重显方案。
80
82
 
81
83
  合法组合必须确定产品、路径/来源、代码状态、语言/框架、服务声明和顺序;发现其他产品时保留。零散信息、`新建` 选择、未选候选或新项目未准备均不能替代完整机器校验。方案送达后仍完整执行 Integration 和 checklist。
82
84
 
@@ -29,11 +29,13 @@ Agent 发给 Integration Worker 的任务正文只允许由下列一句固定说
29
29
  "project_path": "<规范化绝对路径>",
30
30
  "server_language": "<Java|Python|Node.js|C#|PHP>",
31
31
  "framework": "<已确定框架>",
32
- "sandbox_config_state": "<READY|CREATE_PENDING|VERIFY_PENDING>"
32
+ "sandbox_config_state": "<READY|CREATE_PENDING|VERIFY_PENDING>",
33
+ "telemetry_run_id": "<RUN_ID marker 中的当前 run_id>",
34
+ "telemetry_history_count": "<非负整数|null>"
33
35
  }
34
36
  ```
35
37
 
36
- Agent 不得复制、摘录或改写本文件的执行协议,不得在请求中手写任何 `runtime.mjs`、sandbox、verification、acceptance、audit 或 checklist 命令。禁止把完整对话、`integration.start.confirm` stdout、runner evidence、Agent 分析、源码或补丁、完整命令日志、沙箱文件内容、私钥、密码、临时 URL 或此前工具输出复制到 Worker 请求。`skill_dir` 必须是启动器确定的当前 Skill 规范化绝对路径;`sandbox_config_state` 必须是步骤 1 实际取得并在步骤 2 保持有效的终态枚举,不得包含配置内容。
38
+ Agent 不得复制、摘录或改写本文件的执行协议,不得在请求中手写任何 `runtime.mjs`、sandbox、verification、acceptance、audit 或 checklist 命令。禁止把完整对话、`integration.start.confirm` stdout、runner evidence、Agent 分析、源码或补丁、完整命令日志、沙箱文件内容、私钥、密码、临时 URL 或此前工具输出复制到 Worker 请求。`skill_dir` 必须是启动器确定的当前 Skill 规范化绝对路径;`sandbox_config_state` 必须是步骤 1 实际取得并在步骤 2 保持有效的终态枚举,不得包含配置内容。`telemetry_run_id` 只取主 Agent 已解析的当前 `RUN_ID` marker;`telemetry_history_count` 是 Worker 创建前主 Agent 对当前可见历史的诊断快照,无法可靠回顾时为 JSON `null`。两者只供原 flow 登记 stage 使用,不改变 Worker 的业务范围。
37
39
 
38
40
  调用提交成功后,Integration 执行权立即且不可逆地转移给该 Worker。Agent 不得因等待、返回格式或 Worker 失败重新取回本轮 Integration 执行权。
39
41
 
@@ -42,13 +44,15 @@ Agent 不得复制、摘录或改写本文件的执行协议,不得在请求
42
44
  Integration Worker 使用输入事实执行下列原 flow 入口:
43
45
 
44
46
  ```bash
45
- node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" flow integration development --product-type "$PRODUCT_TYPE"
47
+ node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" flow integration development --product-type "$PRODUCT_TYPE" --telemetry-run-id "$TELEMETRY_RUN_ID" --telemetry-history-count "$TELEMETRY_HISTORY_COUNT"
46
48
  ```
47
49
 
48
- 随后严格按照该入口加载的原 `integration/flow.md`,从步骤 3 对步骤 1 的实际沙箱终态进行复核或保持待配置状态,再完整执行步骤 4 至步骤 8。阶段读取、命令、沙箱状态、代码实现、verification、acceptance、checklist 和失败转移都只以原 flow 为准;本文件不另行定义或覆盖业务流程。
50
+ 随后严格按照该入口加载的原 `integration/flow.md`,从步骤 3 对步骤 1 的实际沙箱终态进行复核或保持待配置状态,再完整执行步骤 4 至步骤 8。阶段读取、命令、沙箱状态、代码实现、verification、acceptance、checklist 和失败转移都只以原 flow 为准;本文件不另行定义或覆盖业务流程。Worker 期间主 Agent 不处理新业务消息,因此各 stage 沿用该诊断 history 快照;正式 `user_input_after_clarify_intent` 仍由每个 event 生成时读取 runtime counter,不从 Worker 输入计算。原 flow 中能生成 stage 的 runtime 命令必须继续携带同一对 `--telemetry-run-id/--telemetry-history-count` 参数。
49
51
 
50
52
  Integration Worker 不执行 Onboarding、self-update、`telemetry start-run`、产品/项目重新决策或原 flow 之外的沙箱调用和诊断。不得用 Worker 自报代替原 flow 要求的实际脚本终态和校验证据。
51
53
 
54
+ 遇到阻塞时,先判断是否能在当前授权和工具范围内自行解决;能解决就继续处理并验证,不能解决才返回 STOP。不得将单次失败或尚未定位原因视为无法继续。恢复仍遵守原 flow 的权限、失败分支和重试边界;有新证据或可验证的修复方向时继续,无新进展时停止重复尝试并如实说明,不伪造通过。STOP 的 `remaining_actions` 须简短列明实际错误、已尝试的恢复及所需外部条件;尚未确认的原因明确标为未知,不返回源码、完整日志或敏感值。
55
+
52
56
  原 flow 要求对客送达的登记 runner/script stdout 都要进入交接对象。`integration.start.confirm` 已由主 Agent 在 Worker 转移前按唯一 marker 独立交付;Worker 从步骤 3 开始,以 flow、消息目录和 runner 契约为准收集后续对客 stdout,其中 `sandbox.configuration.pending`、`sandbox.environment.summary`、`integration.safety.closeout` 和 `integration.checklist.result` 必须各自带唯一 `CUSTOMER_MESSAGE_DELIVERY_REQUIRED=<messageId>` marker,缺失、重复或对应正文为空时按交接失败处理;按发生顺序剔除 `ALIPAY_AIPAY_INTERNAL:` 行后保存到 `customer_messages`。过程 stdout、分析、命令和日志不得进入交接对象。登记正文不改写、不总结;空正文不加入。沙箱账号只允许存在于原始登记正文中,不得拆出、复述或进入其他字段。返回结果只依据最终 checklist 的实际证据;只有原 flow 允许衔接时 `next_phase=ONBOARDING`,其他情况为 `STOP`。
53
57
 
54
58
  ## 返回协议
@@ -74,6 +78,8 @@ Integration Worker 不执行 Onboarding、self-update、`telemetry start-run`、
74
78
  - 沙箱 `READY` 且只剩原 flow 允许的非阻塞人工项:`部分完成,人工待验证`、`ONBOARDING`;
75
79
  - 其他代码、安全、必要依据或协议缺口:`未通过`、`STOP`。
76
80
 
77
- 上述七个字段都由 Integration Worker 根据原 flow 的实际结果生成。`protocol` 必须精确为 `INTEGRATION_WORKER_V1`,返回对象只允许包含这七个字段。`sandbox_config_state` 必须复用输入后按步骤 3 实际复核得到的终态,不接受 `null` 或字符串 `"null"`。`manual_verification_items` 和 `remaining_actions` 只保留最终 checklist 已证实的短项;没有时传空数组。禁止返回项目路径、语言、框架、changed files、依赖列表、源码、收据、绝对路径、配置字段或 Worker 分析。Agent 只做一次结构校验,不解释、修复、补充、改写或追问 Worker 返回。校验通过后,按数组顺序把 `customer_messages` 每一项原文作为可见消息送达,不加旁白;然后丢弃该数组。`next_phase=ONBOARDING` 时只把产品、`integration_result`、`sandbox_config_state`、`manual_verification_items` 和 `remaining_actions` 带入独立 Onboarding;不读取项目、不复查 Worker、不重跑 Integration。`protocol`、`customer_messages` 和 `next_phase` 不带入 Onboarding。`next_phase=STOP` 时在送达登记正文后停止,不进入 Onboarding。
81
+ 上述七个字段都由 Integration Worker 根据原 flow 的实际结果生成。`protocol` 必须精确为 `INTEGRATION_WORKER_V1`,返回对象只允许包含这七个字段;telemetry 输入不得回传。`sandbox_config_state` 必须复用输入后按步骤 3 实际复核得到的终态,不接受 `null` 或字符串 `"null"`。`manual_verification_items` 和 `remaining_actions` 只保留最终 checklist 已证实的短项;STOP 时 `remaining_actions` 另保留上文要求的脱敏阻塞事实,没有时传空数组。禁止返回项目路径、语言、框架、changed files、依赖列表、源码、收据、绝对路径、配置字段或 Worker 分析。Agent 对每次返回做结构校验,不自行解释、修复、补充或改写结果;仅允许下文规定的同 Worker 核实。结构合法的 STOP 若缺少阻塞依据,或仍存在授权范围内未尝试的恢复方向,在对客送达前最多要求同一 Worker 核实并继续一次;只指出返回中的证据缺口,不读取项目、不创建新 Worker、不接手 Integration。Worker 从当前实际状态继续,不重做已成功动作,仍按原 flow 修复、重检并返回同一七字段对象。宿主不支持继续同一 Worker,或再次返回 STOP 时,不循环追问,如实保留未解决项。最终结果校验通过后,按数组顺序把 `customer_messages` 每一项原文作为可见消息送达,不加旁白;然后丢弃该数组。`next_phase=ONBOARDING` 时只把产品、`integration_result`、`sandbox_config_state`、`manual_verification_items` 和 `remaining_actions` 带入独立 Onboarding;不读取项目、不复查 Worker、不重跑 Integration。`protocol`、`customer_messages` 和 `next_phase` 不带入 Onboarding。最终 `next_phase=STOP` 时在送达登记正文后停止,不进入 Onboarding。
82
+
83
+ `next_phase=ONBOARDING` 时,送达登记正文后立即执行 `node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" flow onboarding entry` 并继续流程,不得仅宣布下一步就结束当前轮。
78
84
 
79
85
  Worker 明确失败、超时、返回非单一 JSON、字段非法或门禁矛盾时,本轮 Integration 立即停止。Agent 只报告“Integration Worker 交接失败,本轮已停止以避免重复执行”,不创建第二个 Agent,不追问 Worker,不读取项目,不执行任何 `flow integration`、`sandbox`、`a2m`、verification、acceptance、audit 或 checklist 命令,不进入 Onboarding。即使 Worker 文本中包含可猜测的沙箱状态,也不得由 Agent 补跑或重新展示 `integration.start.confirm`。
@@ -341,26 +341,24 @@ init_alipay_cli_product_from_sales_code() {
341
341
  init_alipay_cli_product "$product_type"
342
342
  }
343
343
 
344
- emit_stage_metric_async() {
344
+ emit_stage_metric() {
345
345
  local stage="${1:-}"
346
- local product_name="${2:-}"
347
- local common_dir telemetry_script
346
+ local run_id="${ALIPAY_AIPAY_TELEMETRY_RUN_ID:-}"
347
+ local history_count="${ALIPAY_AIPAY_TELEMETRY_HISTORY_COUNT:-null}"
348
+ local common_dir telemetry_script telemetry_switch
348
349
  [ -n "$stage" ] || return 0
350
+ [ -n "$run_id" ] || return 0
351
+ telemetry_switch="$(printf '%s' "${ALIPAY_AIPAY_TELEMETRY:-}" | tr '[:upper:]' '[:lower:]')"
352
+ case "$telemetry_switch" in
353
+ 0|false|off|no) return 0 ;;
354
+ esac
349
355
  common_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
350
356
  telemetry_script="${common_dir}/telemetry.mjs"
351
357
  [ -f "$telemetry_script" ] && command -v node >/dev/null 2>&1 || return 0
352
- if [ -n "$product_name" ]; then
353
- if [ "${ALIPAY_AIPAY_TEST_MODE:-0}" = "1" ]; then
354
- node "$telemetry_script" stage-async "$stage" --product-name "$product_name"
355
- else
356
- node "$telemetry_script" stage-async "$stage" --product-name "$product_name" >/dev/null 2>&1
357
- fi
358
+ if [ "${ALIPAY_AIPAY_TEST_MODE:-0}" = "1" ]; then
359
+ node "$telemetry_script" stage "$stage" --run-id "$run_id" --history-count "$history_count"
358
360
  else
359
- if [ "${ALIPAY_AIPAY_TEST_MODE:-0}" = "1" ]; then
360
- node "$telemetry_script" stage-async "$stage"
361
- else
362
- node "$telemetry_script" stage-async "$stage" >/dev/null 2>&1
363
- fi
361
+ node "$telemetry_script" stage "$stage" --run-id "$run_id" --history-count "$history_count" >/dev/null 2>&1
364
362
  fi
365
363
  return 0
366
364
  }
@@ -10,7 +10,7 @@ import { fileURLToPath } from 'node:url';
10
10
 
11
11
  import { isWindowsPlatform } from './platform_compat.mjs';
12
12
  import { renderMessage } from './render_customer_message.mjs';
13
- import { currentRunContext, emitStageMetricAsync, recordTelemetryUserInput, startTelemetryRun, telemetryEnabled } from './telemetry.mjs';
13
+ import { currentRunContext, emitStageMetric, startTelemetryRun, telemetryEnabled } from './telemetry.mjs';
14
14
 
15
15
  const scriptDir = path.dirname(fileURLToPath(import.meta.url));
16
16
  const inspectorPath = path.join(scriptDir, 'project_route_inspector.sh');
@@ -125,11 +125,6 @@ function optional(args, name) {
125
125
  return typeof args[name] === 'string' && args[name].length > 0 ? args[name] : undefined;
126
126
  }
127
127
 
128
- function countUserInput(args) {
129
- const inputId = optional(args, 'input-id');
130
- if (inputId) recordTelemetryUserInput(inputId);
131
- }
132
-
133
128
  function requireCustomerMessageDelivery(messageId, message) {
134
129
  process.stderr.write(`${internalPrefix}CUSTOMER_MESSAGE_DELIVERY_REQUIRED=${messageId}\n`);
135
130
  return message;
@@ -1273,6 +1268,7 @@ function runWindowsSandboxSummary(args) {
1273
1268
  environmentRows: required(args, 'environment-rows')
1274
1269
  });
1275
1270
  const reminder = renderMessage('sandbox.environment.reminder', 'WINDOWS', {});
1271
+ emitStageMetric('integration.create_sandbox');
1276
1272
  return requireCustomerMessageDelivery('sandbox.environment.summary', `${summary}\n\n${reminder}`);
1277
1273
  }
1278
1274
 
@@ -1364,14 +1360,13 @@ async function runChecklistResult(args) {
1364
1360
  input.nextFlowReminder = '代码开发校验通过后将自动进入支付产品-产品开通;未通过时停留在代码开发。';
1365
1361
  }
1366
1362
  }
1367
- emitStageMetricAsync('integration.complete_coding', { productType: variant.toLowerCase() });
1363
+ emitStageMetric('integration.complete_coding');
1368
1364
  const rendered = renderMessage('integration.checklist.result', variant, input);
1369
1365
  return requireCustomerMessageDelivery('integration.checklist.result', rendered);
1370
1366
  }
1371
1367
 
1372
1368
  export async function runIntegrationMessageCli(argv = process.argv) {
1373
1369
  const { command, args } = parseArgs(argv);
1374
- countUserInput(args);
1375
1370
  if (command === 'resolve-project') {
1376
1371
  console.log(runResolveProject(args));
1377
1372
  return;
@@ -4,7 +4,6 @@ import fs from 'node:fs';
4
4
  import path from 'node:path';
5
5
  import process from 'node:process';
6
6
  import { fileURLToPath } from 'node:url';
7
- import { recordTelemetryUserInput } from './telemetry.mjs';
8
7
 
9
8
  const internalPrefix = 'ALIPAY_AIPAY_INTERNAL:';
10
9
  const scriptDir = path.dirname(fileURLToPath(import.meta.url));
@@ -125,7 +124,7 @@ export function runInteractionReplyCli(argv = process.argv) {
125
124
  if (command !== 'confirm' || typeof args.reply !== 'string' || !args.reply) {
126
125
  throw new Error('用法: interaction_reply.mjs confirm --reply <用户原始回复> --input-id <本地用户输入幂等键>');
127
126
  }
128
- recordTelemetryUserInput(required(args, 'input-id'));
127
+ required(args, 'input-id');
129
128
  const decision = isAffirmativeReply(args.reply) ? 'CONFIRMED' : 'REJECTED';
130
129
  process.stderr.write(`${internalPrefix}REPLY_DECISION=${decision}\n`);
131
130
  if (decision === 'REJECTED') process.exitCode = 2;
@@ -6,7 +6,7 @@ import process from 'node:process';
6
6
  import { fileURLToPath } from 'node:url';
7
7
 
8
8
  import { renderDiscoverySummary } from './onboarding_message_runner.mjs';
9
- import { currentRunContext, emitStageMetricAsync, telemetryEnabled } from './telemetry.mjs';
9
+ import { currentRunContext, emitStageMetric, telemetryEnabled } from './telemetry.mjs';
10
10
 
11
11
  const internalPrefix = 'ALIPAY_AIPAY_INTERNAL:';
12
12
  const scriptDir = path.dirname(fileURLToPath(import.meta.url));
@@ -332,7 +332,7 @@ async function runDiscovery(args) {
332
332
  };
333
333
  if (envelope.signing.query_status === 'SUCCESS'
334
334
  && (envelope.signing.sign_status === 'SIGNED_EFFECTIVE' || envelope.signing.sign_status === 'SIGN_SUBMITTED')) {
335
- emitStageMetricAsync('onboarding.confirm_signing', { productType });
335
+ emitStageMetric('onboarding.confirm_signing');
336
336
  }
337
337
  if (globalBlocker) {
338
338
  envelope.global_blocker = globalBlocker;
@@ -13,8 +13,8 @@ import {
13
13
  } from './render_customer_message.mjs';
14
14
  import {
15
15
  currentRunContext,
16
- startTelemetryRun,
17
- recordTelemetryUserInput,
16
+ emitStageMetric,
17
+ startTelemetryRun
18
18
  } from './telemetry.mjs';
19
19
 
20
20
  const internalPrefix = 'ALIPAY_AIPAY_INTERNAL:';
@@ -135,11 +135,6 @@ function optional(args, name) {
135
135
  return typeof args[name] === 'string' && args[name].length > 0 ? args[name] : undefined;
136
136
  }
137
137
 
138
- function countUserInput(args) {
139
- const inputId = optional(args, 'input-id');
140
- if (inputId) recordTelemetryUserInput(inputId);
141
- }
142
-
143
138
  function productFor(args) {
144
139
  const productType = required(args, 'product-type');
145
140
  const mapping = productTypes[productType];
@@ -170,8 +165,8 @@ function runPlatformEntry(args = {}) {
170
165
  if (!['onboarding_only', 'full_process'].includes(rootIntent)) {
171
166
  throw new Error('Windows 产品开通引导缺少有效的当前 Onboarding run context');
172
167
  }
173
- const platformId = runContext?.run_id
174
- || platformIdFromEnv(process.env)
168
+ const platformId = platformIdFromEnv(process.env)
169
+ || runContext?.run_id
175
170
  || '';
176
171
  if (!platformId) {
177
172
  throw new Error('Windows 产品开通引导缺少有效的当前 Onboarding run context');
@@ -1156,6 +1151,10 @@ function closeoutInputFromArgs(args) {
1156
1151
 
1157
1152
  async function runCloseout(args) {
1158
1153
  const variables = closeoutInputFromArgs(args);
1154
+ if (args['product-type'] === 'aipay'
1155
+ && ['已复用', '创建成功,状态未取得', '修改成功,状态未取得', '已完成'].includes(args['service-result'])) {
1156
+ emitStageMetric('onboarding.confirm_service');
1157
+ }
1159
1158
  const rendered = renderMessage('process.partial_result', 'DEFAULT', variables);
1160
1159
  return rendered;
1161
1160
  }
@@ -1234,7 +1233,6 @@ function runApplicationResult(args) {
1234
1233
 
1235
1234
  export async function runOnboardingMessageCli(argv = process.argv) {
1236
1235
  const { command, args } = parseArgs(argv);
1237
- countUserInput(args);
1238
1236
  if (command === 'platform-entry') {
1239
1237
  const message = runPlatformEntry(args);
1240
1238
  if (message) console.log(message);
@@ -5,7 +5,6 @@ import path from 'node:path';
5
5
  import process from 'node:process';
6
6
  import { fileURLToPath } from 'node:url';
7
7
  import { isAffirmativeReply } from './interaction_reply.mjs';
8
- import { recordTelemetryUserInput } from './telemetry.mjs';
9
8
 
10
9
  const internalPrefix = 'ALIPAY_AIPAY_INTERNAL:';
11
10
  const scriptDir = path.dirname(fileURLToPath(import.meta.url));
@@ -34,7 +33,7 @@ function required(args, name) {
34
33
  }
35
34
 
36
35
  function assertRegisteredReply(args, kind) {
37
- recordTelemetryUserInput(required(args, 'input-id'));
36
+ required(args, 'input-id');
38
37
  if (!isAffirmativeReply(required(args, 'reply'))) {
39
38
  process.stderr.write(`${internalPrefix}RECOVERY_INPUT_REJECTED=${kind}\n`);
40
39
  process.exitCode = 2;
@@ -5,7 +5,7 @@ import path from 'node:path';
5
5
  import process from 'node:process';
6
6
  import { fileURLToPath } from 'node:url';
7
7
 
8
- import { startTelemetryRun } from './telemetry.mjs';
8
+ import { currentRunContext, startTelemetryRun } from './telemetry.mjs';
9
9
 
10
10
  const scriptDir = path.dirname(fileURLToPath(import.meta.url));
11
11
  const referencesDir = path.resolve(scriptDir, '../..');
@@ -130,24 +130,58 @@ function assertEnumOption(options, name, allowedValues, { required = true } = {}
130
130
  return value;
131
131
  }
132
132
 
133
+ function applyTelemetryContext(domain, args) {
134
+ if (domain === 'telemetry') return args;
135
+ const remaining = [];
136
+ const values = {};
137
+ for (let index = 0; index < args.length; index += 1) {
138
+ const token = args[index];
139
+ if (token !== '--telemetry-run-id' && token !== '--telemetry-history-count') {
140
+ remaining.push(token);
141
+ continue;
142
+ }
143
+ const value = args[index + 1];
144
+ if (value === undefined || value.startsWith('--')) throw new Error(`参数 ${token} 缺少取值`);
145
+ if (Object.prototype.hasOwnProperty.call(values, token)) throw new Error(`参数 ${token} 重复`);
146
+ values[token] = value;
147
+ index += 1;
148
+ }
149
+ if (values['--telemetry-run-id'] !== undefined) {
150
+ process.env.ALIPAY_AIPAY_TELEMETRY_RUN_ID = values['--telemetry-run-id'];
151
+ } else {
152
+ const activeRun = currentRunContext(process.env);
153
+ if (activeRun && !activeRun.terminal) process.env.ALIPAY_AIPAY_TELEMETRY_RUN_ID = activeRun.run_id;
154
+ }
155
+ if (values['--telemetry-history-count'] !== undefined) {
156
+ const historyCount = values['--telemetry-history-count'];
157
+ if (historyCount !== 'null' && !/^(?:0|[1-9]\d*)$/u.test(historyCount)) {
158
+ throw new Error('--telemetry-history-count 只支持非负整数或 null');
159
+ }
160
+ process.env.ALIPAY_AIPAY_TELEMETRY_HISTORY_COUNT = historyCount;
161
+ } else if (!process.env.ALIPAY_AIPAY_TELEMETRY_HISTORY_COUNT) {
162
+ process.env.ALIPAY_AIPAY_TELEMETRY_HISTORY_COUNT = 'null';
163
+ }
164
+ return remaining;
165
+ }
166
+
133
167
  async function runIntegrationBootstrap(args) {
134
168
  const options = parseRuntimeArgs(args);
135
- assertOnlyOptions(options, ['root-intent', 'product-type', 'input-id']);
169
+ assertOnlyOptions(options, ['root-intent', 'product-type']);
136
170
  const rootIntent = assertEnumOption(options, 'root-intent', ['integration_only']);
137
171
  const productType = assertEnumOption(options, 'product-type', ['aipay', 'webpay', 'apppay'], { required: false });
138
172
  process.env.ALIPAY_AIPAY_ROOT_INTENT = rootIntent;
139
- await startTelemetryRun(rootIntent, productType, options['input-id']);
173
+ await startTelemetryRun(rootIntent, productType);
140
174
  const { runFlowCli } = await import('./flow_loader.mjs');
141
175
  runFlowCli(cliArgv(['integration', 'entry']));
142
176
  }
143
177
 
144
178
  async function runOnboardingBootstrap(args) {
145
179
  const options = parseRuntimeArgs(args);
146
- assertOnlyOptions(options, ['root-intent', 'product-type', 'input-id']);
180
+ assertOnlyOptions(options, ['root-intent', 'product-type']);
147
181
  const rootIntent = assertEnumOption(options, 'root-intent', ['onboarding_only']);
148
182
  const productType = assertEnumOption(options, 'product-type', ['aipay', 'webpay', 'apppay'], { required: false });
149
183
  process.env.ALIPAY_AIPAY_ROOT_INTENT = rootIntent;
150
- await startTelemetryRun(rootIntent, productType, options['input-id']);
184
+ await startTelemetryRun(rootIntent, productType);
151
185
  const { runOnboardingMessageCli } = await import('./onboarding_message_runner.mjs');
152
186
  const platformEntryArgs = ['platform-entry'];
153
187
  await runOnboardingMessageCli(cliArgv(platformEntryArgs));
@@ -223,7 +257,7 @@ async function dispatch(domain, args) {
223
257
  export async function runRuntimeCli(argv = process.argv) {
224
258
  const domain = argv[2] || '';
225
259
  try {
226
- await dispatch(domain, argv.slice(3));
260
+ await dispatch(domain, applyTelemetryContext(domain, argv.slice(3)));
227
261
  } catch (error) {
228
262
  runtimeError(domain, error);
229
263
  process.exitCode = domain === 'self-update' ? 0 : 1;