@alipay/alipay-aipay 1.5.1 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -2
- package/skill/SKILL.md +1 -1
- package/skill/VERSION +1 -1
- package/skill/references/integration/flow.md +51 -73
- package/skill/references/integration/modules/checklist.md +3 -3
- package/skill/references/integration/modules/product-decision.md +1 -1
- package/skill/references/integration/modules/sandbox/a2m-sandbox-test.md +11 -22
- package/skill/references/integration/modules/sandbox/alipay-sandbox-tool.md +1 -1
- package/skill/references/integration/modules/sandbox/sandbox-setup-guide.md +4 -4
- package/skill/references/normal/alipay-cli-env.md +2 -2
- package/skill/references/normal/full-process-routing.md +17 -17
- package/skill/references/normal/json/customer-messages.json +13 -14
- package/skill/references/normal/rejection-guide.md +1 -1
- package/skill/references/normal/scripts/alipay_cli_env.mjs +8 -4
- package/skill/references/normal/scripts/flow_loader.mjs +2 -2
- package/skill/references/normal/scripts/integration_context_runner.mjs +3 -3
- package/skill/references/normal/scripts/integration_message_runner.mjs +3 -3
- package/skill/references/normal/scripts/interaction_reply.mjs +3 -3
- package/skill/references/normal/scripts/onboarding_discovery_runner.mjs +3 -3
- package/skill/references/normal/scripts/onboarding_message_runner.mjs +3 -3
- package/skill/references/normal/scripts/onboarding_recovery_runner.mjs +9 -7
- package/skill/references/normal/scripts/python_script_runner.mjs +10 -8
- package/skill/references/normal/scripts/render_customer_message.mjs +68 -59
- package/skill/references/normal/scripts/runtime.mjs +133 -0
- package/skill/references/normal/scripts/self_update.mjs +8 -6
- package/skill/references/normal/scripts/telemetry.mjs +27 -26
- package/skill/references/normal/self-update.md +2 -2
- package/skill/references/normal/telemetry.md +5 -5
- package/skill/references/onboarding/flow.md +67 -80
- package/skill/references/onboarding/modules/app-release.md +5 -5
- package/skill/references/onboarding/modules/authorization.md +1 -1
- package/skill/references/onboarding/modules/service-registration.md +4 -4
- package/skill/references/runtime-entry.md +30 -30
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
Windows 普通代码开发或完整接入请求未明确要求当前配置沙箱时,记录 `sandboxConfigState=VERIFY_PENDING` 并继续代码实现,不展示资料收集消息。只有用户明确要求现在配置或恢复 Windows 沙箱时,才使用 `../../../normal/json/customer-messages.json` 的既有 `sandbox.windows.manual_setup`,引导用户前往支付宝 AI 付站点的“选择产品 → 一站式接入 → 技术集成”页面获取当前沙箱的 APPID、公私钥和账号信息;随后只处理用户针对本轮该消息提供的资料,完整时校验并写入目标项目实际使用的本地敏感配置,部分或错误时只补问对应字段。不得要求用户自行配置、理解 `sandbox_config.sh`、执行 Bash 或手工拼接 Skill 的规范化 JSON。该资料输入例外只适用于沙箱,生产环境应用私钥和密码禁止提供给 Agent;Agent 不得在回复、摘要或普通日志中复述收到的值。
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
node
|
|
20
|
+
node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" integration-message windows-sandbox-setup
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
### 1.3 其他说明
|
|
@@ -135,10 +135,10 @@ Unix/macOS/Linux 创建阶段把实际本机配置路径和 `FLOW:SANDBOX_CONFIG
|
|
|
135
135
|
|
|
136
136
|
### 5.2 对话摘要
|
|
137
137
|
|
|
138
|
-
代码开发完成且配置后置校验通过后,Unix/macOS/Linux 从本文件所在的 `references/integration/modules/sandbox/` 目录使用 `
|
|
138
|
+
代码开发完成且配置后置校验通过后,Unix/macOS/Linux 从本文件所在的 `references/integration/modules/sandbox/` 目录使用 `node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" sandbox summary "<productType>" "<规范化项目路径>" "<已确认服务端语言>"` 复核并展示摘要;该脚本内部负责渲染 `sandbox.environment.summary` 与 `sandbox.environment.reminder`,Agent 不得绕过脚本自写摘要。Windows 使用同一消息目录从项目实际读取的本机配置生成摘要,执行:
|
|
139
139
|
|
|
140
140
|
```powershell
|
|
141
|
-
node
|
|
141
|
+
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"
|
|
142
142
|
```
|
|
143
143
|
|
|
144
144
|
摘要行按当前分支的实际来源依次包含应用 `appId/pid`、商家账号、买家账号及沙箱标识;账号未返回的可选字段直接省略,禁止编造。只有 Unix/macOS/Linux 快速沙箱工具实际返回且已校验的沙箱登录密码和支付密码可以进入摘要行;Windows 手工沙箱虽然允许用户在资料收集时提供当前沙箱密码,Agent 仍不得在摘要或后续回复中复述,只展示非敏感标识和本机保存提示。两类例外都不得扩展到生产环境账号、私钥或密码。
|
|
@@ -174,7 +174,7 @@ renderer 固定输出唯一摘要表、密钥字段已落盘提示和“配置
|
|
|
174
174
|
|
|
175
175
|
`curl` 调用下单接口并取得 HTML 支付表单只属于接口冒烟检查,不能替代用户付款指引,也不能据此标记步骤 6 完成。必须提供用户可在浏览器中打开的支付页面地址;页面打开沙箱收银台后,以下两种体验方式同时告知用户,由用户自行二选一。
|
|
176
176
|
|
|
177
|
-
紧接当前系统对应的网站支付付款指引执行 `node
|
|
177
|
+
紧接当前系统对应的网站支付付款指引执行 `node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" integration-message sandbox-android-client`,统一输出 Android-only、官方直链、直链/页面二维码失败后的开放平台沙箱工具页,以及禁止 iOS、应用市场、第三方站点和自编 URL 的口径。
|
|
178
178
|
|
|
179
179
|
`resultPageInstruction` 必须按实际回跳分支二选一,禁止同时输出两项:
|
|
180
180
|
|
|
@@ -46,7 +46,7 @@ fi
|
|
|
46
46
|
- 本地纯解析、文件检查、`bash -n`、`jq` 校验等不联网命令仍可在默认沙箱内执行。
|
|
47
47
|
|
|
48
48
|
**减少重复授权:**
|
|
49
|
-
- 优先执行 Skill 内置脚本;从本文件所在的 `references/normal/` 目录调用 onboarding 脚本时,使用 `
|
|
49
|
+
- 优先执行 Skill 内置脚本;从本文件所在的 `references/normal/` 目录调用 onboarding 脚本时,使用 `node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" auth ...`、`node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" app ...`、`node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" service ...`,不要把每次 `alipay-cli mcp call` 都展开成新的长命令。
|
|
50
50
|
- 在支持前缀持久授权的工具中,申请可联网权限时使用当前实际脚本绝对路径对应的稳定命令前缀作为授权范围。同一脚本后续不同参数更容易复用授权;不得为了复用授权改调另一份 Skill 副本。
|
|
51
51
|
- 避免用 `DEV_TOOL_NAME=<tool> bash ...`、`PLATFORM=<tool> alipay-cli ...` 作为常规调用形态;这类环境变量前缀会让授权规则更难复用。签约脚本会通过公共初始化设置 `DEV_TOOL_NAME`,直接执行脚本即可。
|
|
52
52
|
- 产品上下文优先通过脚本参数传入,例如 `--sales-code`、`--mcc-code`、`--product-type`;不要用 `PRODUCT_TYPE=... SALES_CODE=... bash ...` 作为常规调用形态。
|
|
@@ -166,7 +166,7 @@ source ~/.bashrc # Linux/bash
|
|
|
166
166
|
|
|
167
167
|
> ⚠️ **强制规范:检测结果仅供内部使用,禁止向用户输出!**
|
|
168
168
|
|
|
169
|
-
AI 编程工具检测使用通用脚本 `scripts/detect_dev_tool.sh`。shell 脚本通过 `scripts/common.sh` 提供的 `init_alipay_cli_context` 初始化 `DEV_TOOL_NAME`、`PLATFORM` 和 `PLATFORM_ID`;其中 `PLATFORM_ID`
|
|
169
|
+
AI 编程工具检测使用通用脚本 `scripts/detect_dev_tool.sh`。shell 脚本通过 `scripts/common.sh` 提供的 `init_alipay_cli_context` 初始化 `DEV_TOOL_NAME`、`PLATFORM` 和 `PLATFORM_ID`;其中 `PLATFORM_ID` 取当前流程 `run_id`,用于关联同一流程,遥测开启或关闭都不影响该值。Onboarding 在产品确认后还通过同一公共脚本把 `aipay|webpay|apppay` 严格映射为 CLI 环境变量 `PRODUCT=AIPAY|WEBPAY|APPPAY`,所有环境检查、登录、查询、写入和文件上传调用都必须携带当前值;该字段不进入 MCP 请求 JSON。Integration 的产品确定前环境检查和快速沙箱仍不传 `PRODUCT`。若宿主环境提供 `COZE_PROJECT_ID`、`MEOO_PROJECT_ID`,或 `MIAODA` 环境下的 `VITE_APP_ID`/`PLATFORM_ID`,新建 run 时优先使用该项目 ID 作为 `run_id`,脚本也会将同一值作为 `PLATFORM_ID`。文档示例或非 shell 流程可直接参考 `detect_dev_tool.sh` 的输出。
|
|
170
170
|
|
|
171
171
|
```
|
|
172
172
|
❌ 禁止:向用户输出"环境检查完成,检测到您正在使用 Claude Code 环境"等检测结果
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# 完整接入编排
|
|
2
2
|
|
|
3
|
-
本文件是 `full_process`
|
|
3
|
+
本文件是 `full_process` 唯一入口。启动方案送达前只复用 Integration 步骤 1 的项目、语言、当前系统分支环境和沙箱准备;不得开发代码、进入 Onboarding 或读取开通信息。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
目标项目和技术栈确定后执行 `node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" flow integration entry`,只加载当前入口阶段并按步骤 1/2 准备及展示方案;代码开发满足衔接条件后执行 `node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" flow onboarding entry`。禁止整读两个 flow。所有 Skill 自有运行时动作只用当前 Skill 绝对路径下的统一入口单命令执行,不前置 `cd`、不拼接管道;用户项目命令仍以已确认项目根为 workdir。
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
其他 Skill 相对命令以 `references/normal/` 为 workdir。`PROJECT_INPUT` 保留用户原话;明确新建项目、网站、商城、应用等产物时固定 `--intent new`,不得因当前目录已有项目改成 `--intent existing`。新建使用空路径或 runner 安全默认目录;复用须选定项目根,未知位置先定位候选。“当前目录”仅在 runner 识别为项目根时接受。扫描和后续脚本只用解析后的规范化绝对路径。
|
|
8
8
|
|
|
9
9
|
## 边界
|
|
10
10
|
|
|
11
|
-
- 只编排 Integration 与 Onboarding,不复制其状态、完成条件和红线。完整接入复用 Integration 步骤 2
|
|
12
|
-
- 先确定项目、语言和创建方式。`NEW_PROJECT` 空路径检查后初始化最小骨架,再执行 Integration 步骤 1;沙箱不依赖产品、不传 `PRODUCT
|
|
11
|
+
- 只编排 Integration 与 Onboarding,不复制其状态、完成条件和红线。完整接入复用 Integration 步骤 2 的唯一非阻塞 `integration.start.confirm`、同一检查器事实和模板,本轮只渲染一次。
|
|
12
|
+
- 先确定项目、语言和创建方式。`NEW_PROJECT` 空路径检查后初始化最小骨架,再执行 Integration 步骤 1;沙箱不依赖产品、不传 `PRODUCT`、不展示摘要,待配置仍继续。代码开发方案送达前禁止读取/展示 MCC、授权范围和开通材料/待办。
|
|
13
13
|
- 项目事实只来自 runner 与实际文件。未知位置用 `locate-projects --search-input "$SEARCH_INPUT" --format message` 查标记并等待选择;不得扫描上层大目录。完整性仍以 Integration 全部适用项和 checklist 为准。
|
|
14
14
|
|
|
15
15
|
## 新项目准备与路由分类
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
`NEW_PROJECT` 只用于初始化前:
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
node scripts/
|
|
22
|
+
node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" integration-message resolve-project --project-input "$PROJECT_INPUT" --base-path "$USER_WORKSPACE_ROOT" --intent new
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
未指定位置时使用用户目录下 `alipay-aipay-projects/pay-demo`,非空占用则加安全后缀。只有 `preparationStatus=READY` 才初始化;其他结果不得清空/覆盖。初始化且沙箱终态确定后单向成为当前会话的 `PREPARED_NEW_PROJECT`;不持久化,重入重扫。`NEW_PROJECT` 不扫描代码,`PREPARED_NEW_PROJECT` 不恢复为空目录状态。
|
|
@@ -36,7 +36,7 @@ node scripts/integration_message_runner.mjs resolve-project --project-input "$PR
|
|
|
36
36
|
项目和沙箱取得确定终态后再确定产品并扫描合法项目分类。已有描述能唯一映射时直接复用;否则只执行下列消息并等待,仍不唯一时重复同一消息。目标产品明确前不得执行 `scan`。
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
|
-
node scripts/
|
|
39
|
+
node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" integration-message product-clarify
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
- `TARGET_PARTIAL`:发现目标代码/配置,仍完整验证;并存时优先。
|
|
@@ -46,37 +46,37 @@ node scripts/integration_message_runner.mjs product-clarify
|
|
|
46
46
|
|
|
47
47
|
合法项目分类与前三种代码状态确认后进入 Integration;`PROJECT_UNRESOLVED/STATUS_UNKNOWN` 继续澄清。Unix/macOS/Linux 的 `CREATE_PENDING|VERIFY_PENDING` 和 Windows 的 `VERIFY_PENDING` 都不阻止扫描/开发。新项目保留 `projectOriginLabel=本轮新建项目`;已有项目“新建”只能新增能力或使用空路径。这些分类只用于本轮分流,不持久化。
|
|
48
48
|
|
|
49
|
-
##
|
|
49
|
+
## 完整接入启动方案
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
合法项目分类、前三种代码状态、产品、语言和框架全部确定后才能输出非阻塞 `integration.start.confirm`。缺项目/技术栈时执行下列 `integration.context.required`;只缺新项目位置用 `integration.project_path.required`。禁止使用 AskUserQuestion、request_user_input、宿主超时默认值、Agent 自创选项或自由话术替代;不得先输出扫描摘要或方案。
|
|
52
52
|
|
|
53
53
|
```bash
|
|
54
|
-
node scripts/
|
|
54
|
+
node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" integration-message context-required --missing-items "$MISSING_ITEMS"
|
|
55
55
|
```
|
|
56
56
|
|
|
57
57
|
`MISSING_ITEMS` 只由 `项目路径`、`技术栈` 组成;产品不明确仍用 `product.clarify`。stdout 原文发出后等待,未补齐前不得初始化、安装或修改。路径输入均先 `resolve-project`;未知位置或需候选时执行:
|
|
58
58
|
|
|
59
59
|
```bash
|
|
60
|
-
node scripts/
|
|
60
|
+
node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" integration-message locate-projects --base-path "$USER_WORKSPACE_ROOT" --search-input "$SEARCH_INPUT" --format message
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
-
字段齐备后执行唯一 runner;禁止拆开执行项目扫描、`jq` 或
|
|
63
|
+
字段齐备后执行唯一 runner;禁止拆开执行项目扫描、`jq` 或 renderer,也不得附加解析。runner stdout 是本动作唯一对客消息,必须把 stdout 原文作为非阻塞消息发给用户;发送后不停止、不等待回复,立即使用同一次 runner 输出的 receipt 进入 development loader。方案事实变化时重新扫描并输出,不使用确认口令;静态扫描只决定进入验证,不证明完成。
|
|
64
64
|
|
|
65
65
|
```bash
|
|
66
|
-
node scripts/
|
|
66
|
+
node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" integration-message start-confirm --product-type "$PRODUCT_TYPE" --product-name "$PRODUCT_NAME" --project-path "$PROJECT_PATH" --project-selection "$PROJECT_SELECTION" --language "$SERVER_LANGUAGE" --framework "$FRAMEWORK"
|
|
67
67
|
```
|
|
68
68
|
|
|
69
69
|
上面命令失败时不得展示手写确认或进入子流程。成功时必须同时保存唯一 `ALIPAY_AIPAY_INTERNAL:PROJECT_CONFIRM_RECEIPT=<receipt>`;缺失、重复或不可解析视为失败。参数必须是当前确定值,禁止直接拼用户输入。runner 校验产品 variant 并固定服务声明;实际范围仍取当前 Integration flow 和 checklist。
|
|
70
70
|
|
|
71
|
-
分流、展示和交接事实必须来自 runner 内同一次 `scan` 对象;禁止用描述、Agent 自报或历史分类代替。`evidence` 仅内部校验,不进 renderer;Onboarding Step 1 前禁止传/猜 `mccCode
|
|
71
|
+
分流、展示和交接事实必须来自 runner 内同一次 `scan` 对象;禁止用描述、Agent 自报或历史分类代替。`evidence` 仅内部校验,不进 renderer;Onboarding Step 1 前禁止传/猜 `mccCode`。方案同时满足 `INT.START.PLAN_DELIVERED` 与 `INT.SERVICE_STATEMENT.DELIVERED` 后,执行 `node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" flow integration development --product-type "$PRODUCT_TYPE" --project-confirm-receipt "$PROJECT_CONFIRM_RECEIPT"`。只有内部 `PROJECT_CONFIRMATION=VALID` 才进入步骤 3;`STALE` 时 loader stdout 已重新渲染当前标准方案,必须原文发送并用新 receipt 立即重试一次,连续变化则停止核对。loader 在原位置记录兼容 stage 和预开发阅读 stage,禁止手工执行 telemetry;receipt 有效时禁止再次渲染 `integration.start.confirm`。
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
合法组合必须确定产品、路径/来源、代码状态、语言/框架、服务声明和顺序;发现其他产品时保留。零散信息、`新建` 选择、未选候选或新项目未准备均不能替代完整机器校验。方案送达并通过 receipt 校验后仍完整执行 Integration 和 checklist。
|
|
74
74
|
|
|
75
75
|
## 子流程衔接规则
|
|
76
76
|
|
|
77
|
-
-
|
|
77
|
+
- 启动方案送达并校验后直接进入 Integration 步骤 3;项目、产品、语言或框架变化时重新扫描并输出新方案。
|
|
78
78
|
- Integration 先完整执行和校验。只有沙箱待配置,或 READY 且仅剩非阻塞人工待验证项时,保持“部分通过”进入 Onboarding;其他代码、安全或依据缺口停在 Integration,不提前登录或收集开通材料。
|
|
79
|
-
- 阶段间只复用有效的产品、项目、代码产物和 CLI 检查,不再询问是否进入 Onboarding
|
|
79
|
+
- 阶段间只复用有效的产品、项目、代码产物和 CLI 检查,不再询问是否进入 Onboarding;Onboarding 只保留非阻塞方案展示。
|
|
80
80
|
- 授权后分别查询签约、应用和适用服务;分支独立,单分支失败不回滚其他成功,认证/授权不匹配或主体变化全局阻断。一次只收集一个类别,提前材料直接校验且不重复索取。
|
|
81
81
|
- 签约材料通过后直接提交;服务创建摘要后直接创建,修改仍确认;当前候选列表选择“新建”且重查未变化后直接创建,用户公钥直接生成官方确认页,校验成功后直接提审。均不增加额外确认点;按量付费沙箱测试仍属 Integration 默认动作。
|
|
82
82
|
- 当前终点汇总代码、沙箱、签约、服务、应用和待办;人工待验证项带入 Onboarding Step 6,不增加确认。有待生效/审核/验证或配置缺口时不得宣称生产就绪。
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"interactionPrompts": {
|
|
4
4
|
"confirmInputHint": "如确认,可以回复“继续”“确认”“OK”,也可以输入 1;如需调整,请直接说明。",
|
|
5
|
+
"planAdjustmentHint": "如需调整方案,请中断 Agent 执行并进行补充说明。",
|
|
5
6
|
"authorizationCompletionInputHint": "授权完成后可回复“继续”“好了”“OK”或输入 1",
|
|
6
7
|
"publicKeyConfirmationCompletionInputHint": "支付宝扫码确认应用公钥完成后可回复“继续”“好了”“OK”或输入 1",
|
|
7
8
|
"completionInputHint": "完成后可回复“继续”“好了”“已完成”“OK”或输入 1;如需调整,请直接说明。",
|
|
@@ -109,10 +110,9 @@
|
|
|
109
110
|
"messageId": "integration.start.confirm",
|
|
110
111
|
"owner": "catalog_owned",
|
|
111
112
|
"trigger": "integration.step2.ready",
|
|
112
|
-
"blocking":
|
|
113
|
-
"
|
|
114
|
-
"
|
|
115
|
-
"expiresWithPrompt": true,
|
|
113
|
+
"blocking": false,
|
|
114
|
+
"allowedReplies": [],
|
|
115
|
+
"postRenderHintType": "planAdjustment",
|
|
116
116
|
"variables": [
|
|
117
117
|
{ "name": "productName", "type": "enum", "required": true, "values": ["AI 按量付费", "AI 网页应用收款", "AI 移动应用收款"] },
|
|
118
118
|
{ "name": "projectPath", "type": "path", "required": true },
|
|
@@ -126,7 +126,7 @@
|
|
|
126
126
|
"requiredPolicyIds": ["P-PROJECT-PROTECT", "P-SENSITIVE-STATE"],
|
|
127
127
|
"variants": {
|
|
128
128
|
"AIPAY": { "templateLines": [
|
|
129
|
-
"
|
|
129
|
+
"代码开发方案:",
|
|
130
130
|
"",
|
|
131
131
|
"| 项目 | 内容 |",
|
|
132
132
|
"|---|---|",
|
|
@@ -142,7 +142,7 @@
|
|
|
142
142
|
"2. 生产环境账号密码、API Keys、应用私钥等敏感信息切勿暴露给 Agent;仅沙箱环境信息可按本 Skill 的沙箱配置流程提供和使用。"
|
|
143
143
|
] },
|
|
144
144
|
"WEBPAY": { "templateLines": [
|
|
145
|
-
"
|
|
145
|
+
"代码开发方案:", "", "| 项目 | 内容 |", "|---|---|",
|
|
146
146
|
"| 目标产品 | AI 网页应用收款 |", "| 项目路径 | `{{projectPath}}` |", "| 项目来源 | {{projectOriginLabel}} |",
|
|
147
147
|
"| 代码开发状态 | {{integrationStatus}} |", "| 检测到的其他支付产品 | {{otherProducts}} |",
|
|
148
148
|
"| 语言 / 框架 | {{language}} / {{framework}} |",
|
|
@@ -151,7 +151,7 @@
|
|
|
151
151
|
"2. 生产环境账号密码、API Keys、应用私钥等敏感信息切勿暴露给 Agent;仅沙箱环境信息可按本 Skill 的沙箱配置流程提供和使用。"
|
|
152
152
|
] },
|
|
153
153
|
"APPPAY": { "templateLines": [
|
|
154
|
-
"
|
|
154
|
+
"代码开发方案:", "", "| 项目 | 内容 |", "|---|---|",
|
|
155
155
|
"| 目标产品 | AI 移动应用收款 |", "| 项目路径 | `{{projectPath}}` |", "| 项目来源 | {{projectOriginLabel}} |",
|
|
156
156
|
"| 代码开发状态 | {{integrationStatus}} |", "| 检测到的其他支付产品 | {{otherProducts}} |",
|
|
157
157
|
"| 语言 / 框架 | {{language}} / {{framework}} |",
|
|
@@ -167,10 +167,9 @@
|
|
|
167
167
|
"messageId": "onboarding.plan.confirm",
|
|
168
168
|
"owner": "catalog_owned",
|
|
169
169
|
"trigger": "onboarding.step2.ready",
|
|
170
|
-
"blocking":
|
|
171
|
-
"
|
|
172
|
-
"
|
|
173
|
-
"expiresWithPrompt": true,
|
|
170
|
+
"blocking": false,
|
|
171
|
+
"allowedReplies": [],
|
|
172
|
+
"postRenderHintType": "planAdjustment",
|
|
174
173
|
"variables": [
|
|
175
174
|
{ "name": "mccCode", "type": "mccCode", "required": true },
|
|
176
175
|
{ "name": "mccName", "type": "singleLine", "required": true },
|
|
@@ -179,7 +178,7 @@
|
|
|
179
178
|
"requiredPolicyIds": ["P-AUTH-BEFORE-ONBOARDING", "P-URL-AUTO-OPEN"],
|
|
180
179
|
"variants": {
|
|
181
180
|
"AIPAY": { "templateLines": [
|
|
182
|
-
"
|
|
181
|
+
"产品开通方案:",
|
|
183
182
|
"",
|
|
184
183
|
"| 项目 | 内容 |",
|
|
185
184
|
"|---|---|",
|
|
@@ -196,7 +195,7 @@
|
|
|
196
195
|
"暂不支持企业账号通过 Skill 完成产品开通,企业账号如需开通请前往支付宝商家平台(https://b.alipay.com/page/portal/home)"
|
|
197
196
|
] },
|
|
198
197
|
"WEBPAY": { "templateLines": [
|
|
199
|
-
"
|
|
198
|
+
"产品开通方案:", "", "| 项目 | 内容 |", "|---|---|",
|
|
200
199
|
"| 产品 | AI 网页应用收款 |", "| 产品码 | `I1080300001000041203` |", "| 经营类目 | {{mccName}} (`{{mccCode}}`) |", "| 特殊资质 | {{mccQualification}} |",
|
|
201
200
|
"| 授权范围 | `app:all,fast_instant_trade_pay:write` |",
|
|
202
201
|
"| 材料预告 | 1、未签约时收集首页、商品页、支付页 3 张截图;支付页是展示支付宝付款方式,等待用户去支付的页面;2、新建应用设置应用公钥时由用户提供 |",
|
|
@@ -208,7 +207,7 @@
|
|
|
208
207
|
] },
|
|
209
208
|
"APPPAY": {
|
|
210
209
|
"templateLines": [
|
|
211
|
-
"
|
|
210
|
+
"产品开通方案:", "", "| 项目 | 内容 |", "|---|---|",
|
|
212
211
|
"| 产品 | AI 移动应用收款 |", "| 产品码 | `I1080300001000041313` |", "| 经营类目 | {{mccName}} (`{{mccCode}}`) |", "| 特殊资质 | {{mccQualification}} |",
|
|
213
212
|
"| 授权范围 | `app:all,auth_alipay_apppay:write` |",
|
|
214
213
|
"| 材料预告 | 1、未签约时收集 APP 名称和首页、商品页、支付页 3 张截图;支付页是展示支付宝付款方式,等待用户去支付的页面;2、新建应用支持 iOS、Android 或 ALL(二者同时);3、新建应用设置应用公钥时由用户提供 |",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
当用户提及以下不支持的产品时,使用 `json/customer-messages.json` 的 `product.unsupported`,传入用户实际产品名。必须执行:
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
|
-
node scripts/
|
|
13
|
+
node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" integration-message product-unsupported --product-name "$PRODUCT_NAME"
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
支持范围、开放平台文档、传统支付集成 Skill 和商家平台链接只在消息目录维护;本文件不复制标准正文。
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import process from 'node:process';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
4
6
|
|
|
5
7
|
import { checkCliEnvironment, isWindowsPlatform } from './platform_compat.mjs';
|
|
6
8
|
import { emitStageMetricAsync } from './telemetry.mjs';
|
|
7
9
|
|
|
8
|
-
function
|
|
9
|
-
const mode =
|
|
10
|
-
if (!['check', 'integration-check'].includes(mode) ||
|
|
10
|
+
export function runAlipayCliEnvCli(argv = process.argv) {
|
|
11
|
+
const mode = argv[2];
|
|
12
|
+
if (!['check', 'integration-check'].includes(mode) || argv.length !== 3) {
|
|
11
13
|
console.error('用法: node alipay_cli_env.mjs <check|integration-check>');
|
|
12
14
|
process.exitCode = 1;
|
|
13
15
|
return;
|
|
@@ -30,4 +32,6 @@ function main() {
|
|
|
30
32
|
console.log(`CLI_ENV_MISSING=${missing.join(',')}`);
|
|
31
33
|
}
|
|
32
34
|
|
|
33
|
-
|
|
35
|
+
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
36
|
+
runAlipayCliEnvCli();
|
|
37
|
+
}
|
|
@@ -199,7 +199,7 @@ function parseOptions(argv) {
|
|
|
199
199
|
return options;
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
-
function
|
|
202
|
+
export function runFlowCli(argv = process.argv) {
|
|
203
203
|
const flow = argv[2];
|
|
204
204
|
const phase = argv[3];
|
|
205
205
|
if (!flow || !phase) throw new Error('用法: flow_loader.mjs <integration|onboarding> <phase> [阶段参数]');
|
|
@@ -233,7 +233,7 @@ function main(argv = process.argv) {
|
|
|
233
233
|
|
|
234
234
|
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
235
235
|
try {
|
|
236
|
-
|
|
236
|
+
runFlowCli();
|
|
237
237
|
} catch (error) {
|
|
238
238
|
console.error(`FLOW_LOADER_ERROR:${error.message}`);
|
|
239
239
|
process.exitCode = 1;
|
|
@@ -147,8 +147,8 @@ export function resolveIntegrationContext(productType, serverLanguage) {
|
|
|
147
147
|
};
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
-
function
|
|
151
|
-
const { command, args } = parseArgs(
|
|
150
|
+
export function runIntegrationContextCli(argv = process.argv) {
|
|
151
|
+
const { command, args } = parseArgs(argv);
|
|
152
152
|
if (command !== 'resolve') {
|
|
153
153
|
throw new Error('用法: integration_context_runner.mjs resolve --product-type <aipay|webpay|apppay> --server-language <language>');
|
|
154
154
|
}
|
|
@@ -158,7 +158,7 @@ function main() {
|
|
|
158
158
|
|
|
159
159
|
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
160
160
|
try {
|
|
161
|
-
|
|
161
|
+
runIntegrationContextCli();
|
|
162
162
|
} catch (error) {
|
|
163
163
|
process.stderr.write(`${internalPrefix}INTEGRATION_CONTEXT_ERROR=${String(error?.message || error).replace(/[\r\n]/gu, ' ')}\n`);
|
|
164
164
|
process.exitCode = 1;
|
|
@@ -957,8 +957,8 @@ async function runChecklistResult(args) {
|
|
|
957
957
|
return rendered;
|
|
958
958
|
}
|
|
959
959
|
|
|
960
|
-
async function
|
|
961
|
-
const { command, args } = parseArgs(
|
|
960
|
+
export async function runIntegrationMessageCli(argv = process.argv) {
|
|
961
|
+
const { command, args } = parseArgs(argv);
|
|
962
962
|
if (command === 'resolve-project') {
|
|
963
963
|
console.log(runResolveProject(args));
|
|
964
964
|
return;
|
|
@@ -1034,7 +1034,7 @@ async function main() {
|
|
|
1034
1034
|
}
|
|
1035
1035
|
|
|
1036
1036
|
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
1037
|
-
|
|
1037
|
+
runIntegrationMessageCli().catch((error) => {
|
|
1038
1038
|
console.error(`INTEGRATION_MESSAGE_ERROR:${error.message}`);
|
|
1039
1039
|
process.exitCode = 1;
|
|
1040
1040
|
});
|
|
@@ -113,8 +113,8 @@ function parseArgs(argv) {
|
|
|
113
113
|
return { command, args };
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
function
|
|
117
|
-
const { command, args } = parseArgs(
|
|
116
|
+
export function runInteractionReplyCli(argv = process.argv) {
|
|
117
|
+
const { command, args } = parseArgs(argv);
|
|
118
118
|
if (command !== 'confirm' || typeof args.reply !== 'string' || !args.reply) {
|
|
119
119
|
throw new Error('用法: interaction_reply.mjs confirm --reply <用户原始回复>');
|
|
120
120
|
}
|
|
@@ -125,7 +125,7 @@ function main() {
|
|
|
125
125
|
|
|
126
126
|
if (process.argv[1] && fileURLToPath(import.meta.url) === path.resolve(process.argv[1])) {
|
|
127
127
|
try {
|
|
128
|
-
|
|
128
|
+
runInteractionReplyCli();
|
|
129
129
|
} catch (error) {
|
|
130
130
|
process.stderr.write(`${internalPrefix}REPLY_VALIDATION_ERROR=${String(error?.message || error).replace(/[\r\n]/gu, ' ')}\n`);
|
|
131
131
|
process.exitCode = 1;
|
|
@@ -208,8 +208,8 @@ async function runDiscovery(args) {
|
|
|
208
208
|
return globalBlocker ? 2 : 0;
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
-
async function
|
|
212
|
-
const { command, args } = parseArgs(
|
|
211
|
+
export async function runOnboardingDiscoveryCli(argv = process.argv) {
|
|
212
|
+
const { command, args } = parseArgs(argv);
|
|
213
213
|
if (command !== 'run') {
|
|
214
214
|
throw new Error('用法: onboarding_discovery_runner.mjs run --product-type <aipay|webpay|apppay> --sales-code <code> [--reuse-sign-status <status> --reuse-sign-flow <flow>]');
|
|
215
215
|
}
|
|
@@ -217,7 +217,7 @@ async function main() {
|
|
|
217
217
|
}
|
|
218
218
|
|
|
219
219
|
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
220
|
-
|
|
220
|
+
runOnboardingDiscoveryCli().catch((error) => {
|
|
221
221
|
process.stderr.write(`${internalPrefix}DISCOVERY_RUNNER_ERROR=${String(error?.message || error).replace(/[\r\n]/gu, ' ')}\n`);
|
|
222
222
|
process.exitCode = 1;
|
|
223
223
|
});
|
|
@@ -542,8 +542,8 @@ function runApplicationResult(args) {
|
|
|
542
542
|
});
|
|
543
543
|
}
|
|
544
544
|
|
|
545
|
-
async function
|
|
546
|
-
const { command, args } = parseArgs(
|
|
545
|
+
export async function runOnboardingMessageCli(argv = process.argv) {
|
|
546
|
+
const { command, args } = parseArgs(argv);
|
|
547
547
|
if (command === 'platform-entry') {
|
|
548
548
|
const message = runPlatformEntry();
|
|
549
549
|
if (message) console.log(message);
|
|
@@ -636,7 +636,7 @@ async function main() {
|
|
|
636
636
|
}
|
|
637
637
|
|
|
638
638
|
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
639
|
-
|
|
639
|
+
runOnboardingMessageCli().catch((error) => {
|
|
640
640
|
console.error(`ONBOARDING_MESSAGE_ERROR:${error.message}`);
|
|
641
641
|
process.exitCode = 1;
|
|
642
642
|
});
|
|
@@ -81,16 +81,18 @@ function runApplicationKeyRecovery(args) {
|
|
|
81
81
|
runScript('app.sh', argv, { ...process.env, ALIPAY_AIPAY_RECOVERY_QUERY_ONCE: '1' });
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
function
|
|
85
|
-
const { command, args } = parseArgs(
|
|
84
|
+
export function runOnboardingRecoveryCli(argv = process.argv) {
|
|
85
|
+
const { command, args } = parseArgs(argv);
|
|
86
86
|
if (command === 'auth-confirm') return runAuthConfirm(args);
|
|
87
87
|
if (command === 'application-key') return runApplicationKeyRecovery(args);
|
|
88
88
|
throw new Error('用法: onboarding_recovery_runner.mjs <auth-confirm|application-key> --reply <明确完成表达> ...');
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
91
|
+
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
92
|
+
try {
|
|
93
|
+
runOnboardingRecoveryCli();
|
|
94
|
+
} catch (error) {
|
|
95
|
+
process.stderr.write(`${internalPrefix}RECOVERY_RUNNER_ERROR=${String(error?.message || error).replace(/[\r\n]/gu, ' ')}\n`);
|
|
96
|
+
process.exitCode = 1;
|
|
97
|
+
}
|
|
96
98
|
}
|
|
@@ -30,8 +30,8 @@ function resolvePython() {
|
|
|
30
30
|
return candidates.find(({ command, prefix }) => commandRuns(command, [...prefix, '--version'])) || null;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
function
|
|
34
|
-
const scriptInput =
|
|
33
|
+
export function runPythonScriptCli(argv = process.argv) {
|
|
34
|
+
const scriptInput = argv[2];
|
|
35
35
|
if (!scriptInput) throw new Error('缺少 Python 脚本路径');
|
|
36
36
|
const resolvedScript = path.resolve(scriptInput);
|
|
37
37
|
if (resolvedScript !== allowedScript || !fs.existsSync(resolvedScript) || fs.lstatSync(resolvedScript).isSymbolicLink()) {
|
|
@@ -40,7 +40,7 @@ function main() {
|
|
|
40
40
|
|
|
41
41
|
const python = resolvePython();
|
|
42
42
|
if (!python) throw new Error('未找到可用的 Python 3 运行时');
|
|
43
|
-
const result = spawnSync(python.command, [...python.prefix, resolvedScript, ...
|
|
43
|
+
const result = spawnSync(python.command, [...python.prefix, resolvedScript, ...argv.slice(3)], {
|
|
44
44
|
stdio: 'inherit',
|
|
45
45
|
shell: false
|
|
46
46
|
});
|
|
@@ -48,9 +48,11 @@ function main() {
|
|
|
48
48
|
process.exitCode = Number.isInteger(result.status) ? result.status : 1;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
52
|
+
try {
|
|
53
|
+
runPythonScriptCli();
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.error(`PYTHON_RUNNER_ERROR:${error.message}`);
|
|
56
|
+
process.exitCode = 1;
|
|
57
|
+
}
|
|
56
58
|
}
|