@alipay/alipay-aipay 1.7.3 → 1.7.5
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/dist/commands/install.js +24 -17
- package/package.json +3 -3
- package/skill/SKILL.md +24 -2
- package/skill/VERSION +1 -1
- package/skill/references/normal/json/customer-messages.json +1 -1
- package/skill/references/normal/scripts/channel_offer.mjs +227 -0
- package/skill/references/normal/scripts/runtime.mjs +3 -1
- package/skill-pre/SKILL.md +23 -3
- package/skill-pre/VERSION +1 -1
- package/skill-pre/references/integration/flow.md +43 -25
- package/skill-pre/references/integration/modules/checklist.md +4 -4
- package/skill-pre/references/integration/modules/sandbox/sandbox-setup-guide.md +33 -33
- package/skill-pre/references/integration/modules/scripts/local_402_sandbox_pay.py +3 -3
- package/skill-pre/references/integration/modules/scripts/sandbox_config.sh +12 -2
- package/skill-pre/references/normal/alipay-cli-env.md +3 -1
- package/skill-pre/references/normal/conversation-telemetry.md +2 -2
- package/skill-pre/references/normal/full-process-routing.md +2 -2
- package/skill-pre/references/normal/json/policy-rules.json +1 -1
- package/skill-pre/references/normal/scripts/alipay_cli_env.mjs +9 -0
- package/skill-pre/references/normal/scripts/alipay_cli_refresh.mjs +10 -1
- package/skill-pre/references/normal/scripts/auth_runtime_runner.mjs +4 -1
- package/skill-pre/references/normal/scripts/common.sh +11 -1
- package/skill-pre/references/normal/scripts/onboarding_discovery_runner.mjs +4 -1
- package/skill-pre/references/normal/scripts/onboarding_message_runner.mjs +17 -2
- package/skill-pre/references/normal/scripts/onboarding_recovery_runner.mjs +4 -1
- package/skill-pre/references/normal/scripts/open_official_url.sh +10 -2
- package/skill-pre/references/normal/scripts/python_script_runner.mjs +9 -4
- package/skill-pre/references/normal/scripts/render_customer_message.mjs +4 -2
- package/skill-pre/references/normal/scripts/runtime.mjs +50 -6
- package/skill-pre/references/normal/scripts/telemetry.mjs +9 -0
- package/skill-pre/references/normal/scripts/windows/acl-native.mjs +3 -0
- package/skill-pre/references/normal/scripts/windows/acl.mjs +41 -0
- package/skill-pre/references/normal/scripts/windows/bin/alipay-cli +4 -0
- package/skill-pre/references/normal/scripts/windows/bootstrap-node.ps1 +140 -0
- package/skill-pre/references/normal/scripts/windows/cli-install.mjs +51 -0
- package/skill-pre/references/normal/scripts/windows/cli-process.mjs +11 -0
- package/skill-pre/references/normal/scripts/windows/execution.mjs +51 -0
- package/skill-pre/references/normal/scripts/windows/git-discovery.mjs +42 -0
- package/skill-pre/references/normal/scripts/windows/policy.json +13 -0
- package/skill-pre/references/normal/scripts/windows/preflight.mjs +182 -0
- package/skill-pre/references/normal/scripts/windows/prepare.mjs +89 -0
- package/skill-pre/references/normal/scripts/windows/probe.sh +14 -0
- package/skill-pre/references/normal/scripts/windows/python-execution.mjs +38 -0
- package/skill-pre/references/normal/scripts/windows/python-runtime.mjs +86 -0
- package/skill-pre/references/normal/scripts/windows/routing.mjs +83 -0
- package/skill-pre/references/normal/scripts/windows/shell_helpers.sh +83 -0
- package/skill-pre/references/normal/scripts/windows/winget.mjs +13 -0
- package/skill-pre/references/normal/windows-environment.md +82 -0
- package/skill-pre/references/onboarding/flow.md +4 -1
- package/skill-pre/references/onboarding/modules/scripts/app.sh +1 -0
- package/skill-pre/references/onboarding/modules/scripts/ar_sign_apply.sh +10 -6
- package/skill-pre/references/onboarding/modules/scripts/auth.sh +1 -0
- package/skill-pre/references/runtime-entry.md +13 -4
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 沙箱环境初始化指南
|
|
2
2
|
|
|
3
|
-
本文档是沙箱环境配置的**单一可信来源**。运行时 Agent 在 Unix/macOS/Linux 只执行 integration flow 登记的 `sandbox_config.sh ensure|reverify|verify|summary`;本文档中的字段表和处理顺序是脚本维护契约,不授权 Agent 对 `.alipay-sandbox.json` 运行临时 `jq`、`cat`、`grep`、`ls`、`stat` 或另写解析脚本。
|
|
3
|
+
本文档是沙箱环境配置的**单一可信来源**。运行时 Agent 在 Unix/macOS/Linux 或 Windows READY 只执行 integration flow 登记的 `sandbox_config.sh ensure|reverify|verify|summary`;本文档中的字段表和处理顺序是脚本维护契约,不授权 Agent 对 `.alipay-sandbox.json` 运行临时 `jq`、`cat`、`grep`、`ls`、`stat` 或另写解析脚本。
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
- ✅ **即开即用**:全自动配置网关及应用信息
|
|
12
12
|
- ✅ **安全隔离**:测试环境不涉及真实资金,可放心调试
|
|
13
13
|
|
|
14
|
-
### 1.2 Windows 用户注意事项
|
|
15
|
-
|
|
14
|
+
### 1.2 Windows LEGACY 用户注意事项
|
|
15
|
+
Windows READY 通过兼容层执行 flow 登记的快速沙箱;下述手工分支只适用于 Windows LEGACY。
|
|
16
16
|
|
|
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 不得在回复、摘要或普通日志中复述收到的值。
|
|
17
|
+
Windows LEGACY 普通代码开发或完整接入请求未明确要求当前配置沙箱时,记录 `sandboxConfigState=VERIFY_PENDING` 并继续代码实现,不展示资料收集消息。只有用户明确要求现在配置或恢复 Windows LEGACY 沙箱时,才使用 `../../../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
20
|
node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" integration-message windows-sandbox-setup --agent-platform "<AGENT_PLATFORM>" --session-id "<SESSION_ID>"
|
|
@@ -45,14 +45,14 @@ node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" integration-message win
|
|
|
45
45
|
|
|
46
46
|
### 3.1 获取候选沙箱配置
|
|
47
47
|
|
|
48
|
-
- Unix/macOS/Linux:运行时只执行 integration flow 的 `sandbox_config.sh ensure`;[alipay-sandbox-tool](alipay-sandbox-tool.md) 只记录脚本内部冻结的 MCP 契约和维护依据,不作为 Agent 直调入口。
|
|
49
|
-
- Windows
|
|
48
|
+
- Unix/macOS/Linux 或 Windows READY:运行时只执行 integration flow 的 `sandbox_config.sh ensure`;[alipay-sandbox-tool](alipay-sandbox-tool.md) 只记录脚本内部冻结的 MCP 契约和维护依据,不作为 Agent 直调入口。
|
|
49
|
+
- Windows LEGACY:兼容环境未就绪,按第 1.2 节记录 `READY|VERIFY_PENDING`;该分支不调用 `sandbox_config.sh create|verify`,也不伪造 `FLOW:SANDBOX_CONFIGURED`。
|
|
50
50
|
- 工具返回 `success === true` 只代表拿到候选 `data`;必须完成第 4 节字段完整性校验后,才允许写入正式配置文件。
|
|
51
51
|
- `success !== true`、`data` 缺失或字段不完整时,先执行第 6 节既定重试;耗尽后进入本轮待配置状态,只阻断沙箱字段使用、摘要、配置校验和沙箱测试,不阻断代码实现。
|
|
52
52
|
|
|
53
53
|
### 3.2 脚本内部固定处理顺序
|
|
54
54
|
|
|
55
|
-
Unix/macOS/Linux 快速沙箱由 `sandbox_config.sh` 在内部完成以下动作,运行时 Agent 不逐项重做:
|
|
55
|
+
Unix/macOS/Linux 或 Windows READY 快速沙箱由 `sandbox_config.sh` 在内部完成以下动作,运行时 Agent 不逐项重做:
|
|
56
56
|
|
|
57
57
|
1. 提取候选 `data`。
|
|
58
58
|
2. 按第 4 节逐项校验必含字段。
|
|
@@ -61,25 +61,25 @@ Unix/macOS/Linux 快速沙箱由 `sandbox_config.sh` 在内部完成以下动作
|
|
|
61
61
|
5. 后续由商家服务端代码使用当前语言标准 JSON 解析器在运行时读取该文件并映射到 SDK;Agent 不通过 shell 输出字段原文,也不把沙箱密钥复制到源码或重复写入 `.env`。
|
|
62
62
|
6. 代码开发完成且配置后置校验通过后,再使用第 5.2 节的摘要输出入口对客展示沙箱环境配置。
|
|
63
63
|
|
|
64
|
-
Windows 手工沙箱:
|
|
64
|
+
Windows LEGACY 手工沙箱:
|
|
65
65
|
|
|
66
66
|
1. 没有资料且没有明确配置请求时记录 `VERIFY_PENDING` 并继续代码实现,不渲染消息、不探测猜测配置。
|
|
67
67
|
2. 用户明确要求配置且尚未提供资料时,才使用标准消息一次收集当前沙箱应用的 APPID、支付宝公钥、应用公钥、与已确认语言匹配的应用私钥和沙箱账号信息;缺失或校验失败时只补问对应字段。
|
|
68
68
|
3. 按第 4 节校验资料,随后由 Agent 写入目标项目实际使用的本地敏感配置;不要求采用快速沙箱 `data` 的嵌套结构,不把值复制到源码或普通日志。
|
|
69
|
-
4. 检查敏感配置未被 Git 跟踪,并已有适用于实际路径的版本控制忽略保护;能检查 Windows 文件访问控制时确认仅当前用户可访问,不能取得证据时标记为人工待验证。
|
|
70
|
-
5. 只有 `READY` 时才输出第 5 节规定的摘要和 Windows 提醒并从实际本机配置映射到 SDK;Agent 不得在回复或摘要中复述用户提供的沙箱密钥和密码,生产环境应用私钥和密码禁止提供给 Agent。
|
|
69
|
+
4. 检查敏感配置未被 Git 跟踪,并已有适用于实际路径的版本控制忽略保护;能检查 Windows LEGACY 文件访问控制时确认仅当前用户可访问,不能取得证据时标记为人工待验证。
|
|
70
|
+
5. 只有 `READY` 时才输出第 5 节规定的摘要和 Windows LEGACY 提醒并从实际本机配置映射到 SDK;Agent 不得在回复或摘要中复述用户提供的沙箱密钥和密码,生产环境应用私钥和密码禁止提供给 Agent。
|
|
71
71
|
|
|
72
|
-
Unix/macOS/Linux 快速沙箱的流程准备必须使用 integration flow 登记的 `sandbox_config.sh ensure` 入口:配置缺失时脚本内部创建,已存在时脚本内部复核;步骤 3 仅在首次准备为 `READY` 时执行 `reverify`,待配置时直接继续代码开发;代码开发完成且配置仍为 `READY` 后才使用 `summary` 展示摘要。`ensure|reverify` 会把既定重试耗尽转换为受控 `CREATE_PENDING|VERIFY_PENDING`,直接渲染统一消息并返回终态标记;Agent 不得直接选择创建分支、重复检查文件存在性或权限、读取字段结构、拼接沙箱 JSON、另写解析逻辑或自制摘要表。Windows 手工申领分支检查目标项目实际读取的本地配置,不把平台字段擅自改造成快速沙箱返回结构。
|
|
72
|
+
Unix/macOS/Linux 或 Windows READY 快速沙箱的流程准备必须使用 integration flow 登记的 `sandbox_config.sh ensure` 入口:配置缺失时脚本内部创建,已存在时脚本内部复核;步骤 3 仅在首次准备为 `READY` 时执行 `reverify`,待配置时直接继续代码开发;代码开发完成且配置仍为 `READY` 后才使用 `summary` 展示摘要。`ensure|reverify` 会把既定重试耗尽转换为受控 `CREATE_PENDING|VERIFY_PENDING`,直接渲染统一消息并返回终态标记;Agent 不得直接选择创建分支、重复检查文件存在性或权限、读取字段结构、拼接沙箱 JSON、另写解析逻辑或自制摘要表。Windows LEGACY 手工申领分支检查目标项目实际读取的本地配置,不把平台字段擅自改造成快速沙箱返回结构。
|
|
73
73
|
|
|
74
74
|
---
|
|
75
75
|
|
|
76
76
|
## 4. 字段完整性校验契约(脚本内部卡点)
|
|
77
77
|
|
|
78
|
-
Unix/macOS/Linux 由 `sandbox_config.sh` 内部逐项校验,Agent 只消费退出码和 flow 登记标记,不手工执行本节清单。Windows 没有该脚本能力时,才按目标项目实际配置逐项检查。任一必含字段缺失或为空时立即停止使用当前候选:Unix/macOS/Linux 不得写入正式 `.alipay-sandbox.json`,Windows 不得把当前本机配置标记为可用;Unix/macOS/Linux 按有限重试和待配置终态继续代码实现,Windows 仍使用登记的资料补充出口。
|
|
78
|
+
Unix/macOS/Linux 或 Windows READY 由 `sandbox_config.sh` 内部逐项校验,Agent 只消费退出码和 flow 登记标记,不手工执行本节清单。Windows LEGACY 没有该脚本能力时,才按目标项目实际配置逐项检查。任一必含字段缺失或为空时立即停止使用当前候选:Unix/macOS/Linux 或 Windows READY 不得写入正式 `.alipay-sandbox.json`,Windows LEGACY 不得把当前本机配置标记为可用;Unix/macOS/Linux 或 Windows READY 按有限重试和待配置终态继续代码实现,Windows LEGACY 仍使用登记的资料补充出口。
|
|
79
79
|
|
|
80
80
|
### 4.1 必含字段清单
|
|
81
81
|
|
|
82
|
-
以下是两条分支共同的语义要求,必须按项目语言和测试账号要求存在且非空。Unix/macOS/Linux 快速沙箱按表中的原始字段名检查;Windows 按目标项目实际配置的等价字段检查,不得为了通过校验擅自改造为快速沙箱嵌套结构:
|
|
82
|
+
以下是两条分支共同的语义要求,必须按项目语言和测试账号要求存在且非空。Unix/macOS/Linux 或 Windows READY 快速沙箱按表中的原始字段名检查;Windows LEGACY 按目标项目实际配置的等价字段检查,不得为了通过校验擅自改造为快速沙箱嵌套结构:
|
|
83
83
|
|
|
84
84
|
| 字段 | 说明 |
|
|
85
85
|
|---|---|
|
|
@@ -118,38 +118,38 @@ Unix/macOS/Linux 由 `sandbox_config.sh` 内部逐项校验,Agent 只消费退
|
|
|
118
118
|
|
|
119
119
|
### 5.1 本地配置文件
|
|
120
120
|
|
|
121
|
-
Unix/macOS/Linux 快速沙箱:
|
|
121
|
+
Unix/macOS/Linux 或 Windows READY 快速沙箱:
|
|
122
122
|
|
|
123
123
|
- 固定写入已确认的目标项目根目录 `.alipay-sandbox.json`。目标目录不可写、`.gitignore` 不是安全普通文件或无法建立 Git 忽略保护时不得落盘或使用当前配置;`ensure|reverify` 将其记录为待配置并继续代码实现,不降级写入系统临时目录、Agent 原始工作目录或其他项目。
|
|
124
124
|
- JSON 文件必须保留沙箱返回的原始字段名和嵌套结构,不要转换成 `.env` 扁平键值。
|
|
125
125
|
- 文件权限必须限制为当前用户可读写,即 `chmod 600`;权限收紧或复核失败时不得使用配置或执行沙箱依赖动作。
|
|
126
126
|
- 配置不得已被 Git 跟踪;项目根目录 `.gitignore` 必须包含精确规则 `/.alipay-sandbox.json`。脚本只在缺失时追加一次,不覆盖既有内容;`.gitignore` 为符号链接或非普通文件时停止。
|
|
127
127
|
|
|
128
|
-
Windows 手工沙箱:
|
|
128
|
+
Windows LEGACY 手工沙箱:
|
|
129
129
|
|
|
130
130
|
- 由 Agent 根据目标项目实际结构选择并写入本机敏感配置路径,不要求用户创建 `.alipay-sandbox.json` 或自行配置项目。
|
|
131
|
-
- 配置必须未被 Git 跟踪,并建立适用于该实际路径的忽略保护;不得因为 Windows 不使用 POSIX `0600` 而声称完成了该权限检查。
|
|
132
|
-
- 只有实际检查到的字段才能进入后续 SDK 映射;无法自动核验的 Windows 文件访问控制或平台页面信息必须标记为人工待验证。
|
|
131
|
+
- 配置必须未被 Git 跟踪,并建立适用于该实际路径的忽略保护;不得因为 Windows LEGACY 不使用 POSIX `0600` 而声称完成了该权限检查。
|
|
132
|
+
- 只有实际检查到的字段才能进入后续 SDK 映射;无法自动核验的 Windows LEGACY 文件访问控制或平台页面信息必须标记为人工待验证。
|
|
133
133
|
|
|
134
|
-
Unix/macOS/Linux 创建阶段把实际本机配置路径和 `FLOW:SANDBOX_CONFIG_READY` 作为带 `ALIPAY_AIPAY_INTERNAL:` 前缀的 stderr 内部事实,stdout 为空;不展示账号、密码、公钥或摘要。Windows 手工分支完成后只在内部保留实际本机配置路径。两条分支在代码开发完成且配置后置校验通过后,才进入摘要展示。
|
|
134
|
+
Unix/macOS/Linux 或 Windows READY 创建阶段把实际本机配置路径和 `FLOW:SANDBOX_CONFIG_READY` 作为带 `ALIPAY_AIPAY_INTERNAL:` 前缀的 stderr 内部事实,stdout 为空;不展示账号、密码、公钥或摘要。Windows LEGACY 手工分支完成后只在内部保留实际本机配置路径。两条分支在代码开发完成且配置后置校验通过后,才进入摘要展示。
|
|
135
135
|
|
|
136
136
|
### 5.2 对话摘要
|
|
137
137
|
|
|
138
|
-
代码开发完成且配置后置校验通过后,Unix/macOS/Linux 从本文件所在的 `references/integration/modules/sandbox/` 目录使用 `node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" sandbox summary "<productType>" "<规范化项目路径>" "<已确认服务端语言>" --agent-platform "<AGENT_PLATFORM>" --session-id "<SESSION_ID>"` 复核并展示摘要;该脚本内部负责渲染 `sandbox.environment.summary` 与 `sandbox.environment.reminder`,Agent 不得绕过脚本自写摘要。Windows 使用同一消息目录从项目实际读取的本机配置生成摘要,执行:
|
|
138
|
+
代码开发完成且配置后置校验通过后,Unix/macOS/Linux 或 Windows READY 从本文件所在的 `references/integration/modules/sandbox/` 目录使用 `node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" sandbox summary "<productType>" "<规范化项目路径>" "<已确认服务端语言>" --agent-platform "<AGENT_PLATFORM>" --session-id "<SESSION_ID>"` 复核并展示摘要;该脚本内部负责渲染 `sandbox.environment.summary` 与 `sandbox.environment.reminder`,Agent 不得绕过脚本自写摘要。Windows LEGACY 使用同一消息目录从项目实际读取的本机配置生成摘要,执行:
|
|
139
139
|
|
|
140
140
|
```powershell
|
|
141
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" --agent-platform "<AGENT_PLATFORM>" --session-id "<SESSION_ID>"
|
|
142
142
|
```
|
|
143
143
|
|
|
144
|
-
`environmentRows` 的具体值严禁编造、猜测、补全,禁止使用示例值、占位值或历史对话值替代本轮已校验配置。Unix/macOS/Linux 必须由登记脚本直接读取同一配置并生成四行,Agent 不得手填或改写;Windows 的应用 ID 和买家测试账号必须取自步骤 1/3 已校验的同一本机配置,两个密码行的固定保存提示仅在实际确认密码已写入该文件后使用。任一必需字段缺失、为空、配置无法读取或来源无法确认时,停止摘要展示并按既有配置失败分支处理,禁止为凑齐四行补值。
|
|
144
|
+
`environmentRows` 的具体值严禁编造、猜测、补全,禁止使用示例值、占位值或历史对话值替代本轮已校验配置。Unix/macOS/Linux 或 Windows READY 必须由登记脚本直接读取同一配置并生成四行,Agent 不得手填或改写;Windows LEGACY 的应用 ID 和买家测试账号必须取自步骤 1/3 已校验的同一本机配置,两个密码行的固定保存提示仅在实际确认密码已写入该文件后使用。任一必需字段缺失、为空、配置无法读取或来源无法确认时,停止摘要展示并按既有配置失败分支处理,禁止为凑齐四行补值。
|
|
145
145
|
|
|
146
|
-
摘要动态行固定依次为“沙箱支付宝应用ID(appID)”“沙箱买家测试账号”“沙箱买家登录密码”“沙箱买家支付密码”。Unix/macOS/Linux
|
|
146
|
+
摘要动态行固定依次为“沙箱支付宝应用ID(appID)”“沙箱买家测试账号”“沙箱买家登录密码”“沙箱买家支付密码”。Unix/macOS/Linux 与 Windows READY 都从已校验快速沙箱配置的 `appIds[0].appId`、`sandboxAccounts.user.email`、`sandboxAccounts.user.logonPassword`、`sandboxAccounts.user.payPassword` 取值;Windows LEGACY 手工沙箱只展示前两项实际值,两个密码行固定提示“已写入本地配置文件,默认不在对话中展开”。不得追加 pid、商家或买家 userId、sandboxId;手工沙箱不得将密码原文传入 renderer。以上例外不得扩展到生产环境账号、私钥或密码。
|
|
147
147
|
|
|
148
148
|
renderer 固定输出唯一摘要表、密钥字段已落盘提示和“配置不等于测试通过”的边界。禁止另写字段核对表、独立校验结论,或把表名、前后提示改成“沙箱环境校验通过”“沙箱测试通过”“沙箱环境测试通过”。
|
|
149
149
|
|
|
150
150
|
### 5.3 配置准备完成后提示(卡点)
|
|
151
151
|
|
|
152
|
-
`sandbox.environment.summary` 后立即渲染 `sandbox.environment.reminder`:Unix/macOS/Linux 由 `sandbox_config.sh summary` 使用 `DEFAULT`,Windows 使用上方 `WINDOWS` 命令。该消息说明测试资金边界和配置位置;`DEFAULT` 另提醒代码开发阶段自动配置沙箱,正式上线前由用户替换为产品开通流程取得的线上应用配置。安全控制由脚本执行,详细生产配置与上线要求由步骤 7 的 `integration.safety.closeout` 输出。创建阶段不渲染,不维护文案副本。
|
|
152
|
+
`sandbox.environment.summary` 后立即渲染 `sandbox.environment.reminder`:Unix/macOS/Linux 或 Windows READY 由 `sandbox_config.sh summary` 使用 `DEFAULT`,Windows LEGACY 使用上方 `WINDOWS` 命令。该消息说明测试资金边界和配置位置;`DEFAULT` 另提醒代码开发阶段自动配置沙箱,正式上线前由用户替换为产品开通流程取得的线上应用配置。安全控制由脚本执行,详细生产配置与上线要求由步骤 7 的 `integration.safety.closeout` 输出。创建阶段不渲染,不维护文案副本。
|
|
153
153
|
|
|
154
154
|
### 5.4 沙箱对客展示白名单
|
|
155
155
|
|
|
@@ -157,12 +157,12 @@ renderer 固定输出唯一摘要表、密钥字段已落盘提示和“配置
|
|
|
157
157
|
|
|
158
158
|
| 场景 | 可对客展示 | 禁止对客展示 |
|
|
159
159
|
|---|---|---|
|
|
160
|
-
| Unix/macOS/Linux 快速沙箱摘要 | `sandbox_config.sh summary` 实际渲染的应用 `appId`、买家 `email/logonPassword/payPassword`、配置文件目录 | `appPrivateKey`、`appPrivatePkcsKey`、`alipayPublicKey`、`appPublicKey`、原始 `.alipay-sandbox.json`、完整 MCP 响应 |
|
|
161
|
-
| Unix/macOS/Linux 网站支付付款体验 | 已校验的沙箱买家登录账号、登录密码、支付密码,以及实际支付页面地址和启动命令 | 商家密码、任何公钥/私钥原文、完整支付表单、签名串 |
|
|
162
|
-
| Windows 手工沙箱 | 配置文件目录、实际沙箱应用 ID 和买家登录账号、两个密码的本机保存提示、官方控制台获取与本机配置完成提示 | 用户提供的应用私钥、支付宝公钥、应用公钥、沙箱账号密码原文 |
|
|
160
|
+
| Unix/macOS/Linux 与 Windows READY 快速沙箱摘要 | `sandbox_config.sh summary` 实际渲染的应用 `appId`、买家 `email/logonPassword/payPassword`、配置文件目录 | `appPrivateKey`、`appPrivatePkcsKey`、`alipayPublicKey`、`appPublicKey`、原始 `.alipay-sandbox.json`、完整 MCP 响应 |
|
|
161
|
+
| Unix/macOS/Linux 与 Windows READY 网站支付付款体验 | 已校验的沙箱买家登录账号、登录密码、支付密码,以及实际支付页面地址和启动命令 | 商家密码、任何公钥/私钥原文、完整支付表单、签名串 |
|
|
162
|
+
| Windows LEGACY 手工沙箱 | 配置文件目录、实际沙箱应用 ID 和买家登录账号、两个密码的本机保存提示、官方控制台获取与本机配置完成提示 | 用户提供的应用私钥、支付宝公钥、应用公钥、沙箱账号密码原文 |
|
|
163
163
|
| 按量付费自动联调 | 受控结论、付款链接和沙箱买家可选体验入口 | `Payment-Proof`、`Payment-Validation` 原文、完整收银请求、临时产物路径中的敏感内容 |
|
|
164
164
|
|
|
165
|
-
|
|
165
|
+
仅 Unix/macOS/Linux 与 Windows READY 的 `sandboxCredential` 类型变量可以承载快速沙箱买家登录密码和支付密码;该例外不适用于 Windows LEGACY 手工沙箱或生产账号、生产密码、应用私钥、公钥、token、签名串或 Payment-Proof。
|
|
166
166
|
|
|
167
167
|
### 5.5 网站支付沙箱付款提示(代码生成后、集成收尾前)
|
|
168
168
|
|
|
@@ -172,7 +172,7 @@ renderer 固定输出唯一摘要表、密钥字段已落盘提示和“配置
|
|
|
172
172
|
- **渲染验证**:Agent 具备浏览器/UI 能力时,打开回跳页确认非空白、无可见报错且关键内容正常渲染;不具备时,请用户打开精确地址确认。未取得证据时不得宣称回跳页已验证或网站支付代码开发完成。
|
|
173
173
|
- **关闭分支**:用户已明确表示不使用同步回跳时,不要求或猜测 `return_url`;确认 SDK 请求未传该字段,并验证异步通知、交易查询和商户订单查询页。用户未明确关闭时,缺少 `return_url` 必须修复为默认同步回跳分支。
|
|
174
174
|
|
|
175
|
-
完成对应分支校验后按系统渲染:Unix/macOS/Linux 快速沙箱使用 `webpay.sandbox.experience
|
|
175
|
+
完成对应分支校验后按系统渲染:Unix/macOS/Linux 与 Windows READY 快速沙箱使用 `webpay.sandbox.experience`,传入已校验的沙箱买家账号、登录密码、支付密码、实际项目启动命令、浏览器支付页面地址和当前回跳分支说明;Windows LEGACY 手工沙箱使用 `webpay.sandbox.experience.windows`,只传实际启动命令、浏览器支付页面地址和回跳分支说明,密码由用户从已保存的本机配置或支付宝开放平台控制台取得,Agent 不在付款指引中复述。不得使用示例端口、占位 URL 或猜测地址;任一必需值无法确定时不渲染半模板,指出缺失项并标记为人工待补充。
|
|
176
176
|
|
|
177
177
|
`curl` 调用下单接口并取得 HTML 支付表单只属于接口冒烟检查,不能替代用户付款指引,也不能据此标记步骤 6 完成。必须提供用户可在浏览器中打开的支付页面地址;页面打开沙箱收银台后,以下两种体验方式同时告知用户,由用户自行二选一。
|
|
178
178
|
|
|
@@ -200,8 +200,8 @@ renderer 固定输出唯一摘要表、密钥字段已落盘提示和“配置
|
|
|
200
200
|
2. 禁止用占位符或示例假数据冒充真实返回值。
|
|
201
201
|
3. 禁止假设“工具返回的应该都有”而跳过逐项校验。
|
|
202
202
|
4. 禁止字段不完整时使用当前配置、写入正式 `.alipay-sandbox.json`、执行配置后置校验或沙箱测试;允许继续不读取沙箱字段的代码实现,最终必须标记沙箱配置未完成。
|
|
203
|
-
5. Windows 只允许用户在标准资料收集消息后提供当前沙箱密钥和账号信息,Agent 不得在回复、摘要或日志中复述;Unix/macOS/Linux 只允许按登记消息展示已校验的快速沙箱买家密码。禁止展示生产环境应用私钥、账号密码或把任何密钥长字段整段刷屏输出。
|
|
204
|
-
6. 禁止继续使用已被 Git 跟踪的沙箱敏感配置。Unix/macOS/Linux 快速沙箱还必须具备 `/.alipay-sandbox.json` 精确忽略规则;Windows 必须具备适用于实际本机敏感配置路径的忽略保护。
|
|
203
|
+
5. Windows LEGACY 只允许用户在标准资料收集消息后提供当前沙箱密钥和账号信息,Agent 不得在回复、摘要或日志中复述;Unix/macOS/Linux 或 Windows READY 只允许按登记消息展示已校验的快速沙箱买家密码。禁止展示生产环境应用私钥、账号密码或把任何密钥长字段整段刷屏输出。
|
|
204
|
+
6. 禁止继续使用已被 Git 跟踪的沙箱敏感配置。Unix/macOS/Linux 或 Windows READY 快速沙箱还必须具备 `/.alipay-sandbox.json` 精确忽略规则;Windows LEGACY 必须具备适用于实际本机敏感配置路径的忽略保护。
|
|
205
205
|
|
|
206
206
|
### 6.2 快速沙箱重复创建边界
|
|
207
207
|
|
|
@@ -216,10 +216,10 @@ renderer 固定输出唯一摘要表、密钥字段已落盘提示和“配置
|
|
|
216
216
|
| 创建失败且既定重试耗尽 | `ensure` 使用 `sandbox.configuration.pending/CREATE`,记录 `CREATE_PENDING` 并继续代码实现;代码开发完成后固定提醒用户可对 Agent 说“重新创建并配置沙箱” |
|
|
217
217
|
| 候选字段或已有配置字段复核失败 | 最多自动重试 2 次、每次间隔 3 秒;仍失败时使用 `sandbox.configuration.pending/CREATE|VERIFY` 并继续代码实现,不展示原始字段或响应 |
|
|
218
218
|
| 待配置状态 | 跳过摘要、配置后置校验、按量付费联调和网站支付付款体验;最终 checklist 保持部分通过或未通过,不得宣称代码开发全部通过或生产就绪 |
|
|
219
|
-
| Windows 未提供资料且未明确要求当前配置 | 记录 `VERIFY_PENDING` 并继续代码实现;不输出失败或申领消息,不探测、不读取、不伪造配置 |
|
|
220
|
-
| Windows 手工申领资料或本地项目配置校验未通过 | 使用 `sandbox.create.failure/WINDOWS`;按第 4 节逐项校验,只补问或更正实际缺失、错误字段后由 Agent 更新本机配置,不要求用户执行 Skill 内部脚本,不伪造快速沙箱结果,也不调用快速沙箱重建 |
|
|
219
|
+
| Windows LEGACY 未提供资料且未明确要求当前配置 | 记录 `VERIFY_PENDING` 并继续代码实现;不输出失败或申领消息,不探测、不读取、不伪造配置 |
|
|
220
|
+
| Windows LEGACY 手工申领资料或本地项目配置校验未通过 | 使用 `sandbox.create.failure/WINDOWS`;按第 4 节逐项校验,只补问或更正实际缺失、错误字段后由 Agent 更新本机配置,不要求用户执行 Skill 内部脚本,不伪造快速沙箱结果,也不调用快速沙箱重建 |
|
|
221
221
|
|
|
222
|
-
本模块不维护失败话术副本;Unix/macOS/Linux 待配置正文由 `sandbox.configuration.pending` 固定维护,Windows 缺失字段和恢复动作仍通过 `sandbox.create.failure/WINDOWS` 的受控变量传入。
|
|
222
|
+
本模块不维护失败话术副本;Unix/macOS/Linux 或 Windows READY 待配置正文由 `sandbox.configuration.pending` 固定维护,Windows LEGACY 缺失字段和恢复动作仍通过 `sandbox.create.failure/WINDOWS` 的受控变量传入。
|
|
223
223
|
|
|
224
224
|
---
|
|
225
225
|
|
|
@@ -227,7 +227,7 @@ renderer 固定输出唯一摘要表、密钥字段已落盘提示和“配置
|
|
|
227
227
|
|
|
228
228
|
只有本轮沙箱配置为 `READY` 时,后续步骤才把可信配置接入用户项目并立即做配置准确性后置校验;校验失败时停止联调并修正服务端加载器或 SDK 配置。待配置时只实现会在缺少有效配置时明确失败的加载边界,不读取、复制或伪造沙箱字段。
|
|
229
229
|
|
|
230
|
-
- Unix/macOS/Linux 确认服务端加载器直接读取第 5.1 节的实际 `.alipay-sandbox.json`,从同一 `appIds[0]` 映射 `appId`、应用私钥和支付宝公钥;禁止从对话、历史代码或示例值复制,禁止用 shell 把字段原文输出后再粘贴。Windows 确认项目读取同一套本机沙箱应用配置。
|
|
230
|
+
- Unix/macOS/Linux 或 Windows READY 确认服务端加载器直接读取第 5.1 节的实际 `.alipay-sandbox.json`,从同一 `appIds[0]` 映射 `appId`、应用私钥和支付宝公钥;禁止从对话、历史代码或示例值复制,禁止用 shell 把字段原文输出后再粘贴。Windows LEGACY 确认项目读取同一套本机沙箱应用配置。
|
|
231
231
|
- 检查加载器没有截断、替换、包装或重新编码字段;项目源码、普通日志和额外 `.env` 中不存在沙箱密钥副本。
|
|
232
232
|
- 检查 SDK 配置与私钥字段匹配:`appPrivatePkcsKey` 对应 PKCS#1,`appPrivateKey` 对应 PKCS#8。
|
|
233
233
|
- 检查 SDK 实际接收的私钥值不包含 PEM 头尾、其他前后缀、包装行或说明文字;业务协议直接使用原生密码库签名时,可按密码库要求临时适配调用入参,但不得修改或覆盖原始配置值。
|
|
@@ -230,16 +230,16 @@ def fetch_payment_needed(
|
|
|
230
230
|
method = method.upper()
|
|
231
231
|
if method == "GET":
|
|
232
232
|
if require_status_402:
|
|
233
|
-
headers = run_curl(["-s", "-D", "-", "-o",
|
|
233
|
+
headers = run_curl(["-s", "-D", "-", "-o", os.devnull, "-X", "GET", url])
|
|
234
234
|
payment_needed = parse_payment_needed(headers)
|
|
235
235
|
else:
|
|
236
236
|
headers = run_curl(["-s", "-I", url])
|
|
237
237
|
payment_needed = parse_payment_needed(headers)
|
|
238
238
|
if not payment_needed:
|
|
239
|
-
headers = run_curl(["-s", "-D", "-", "-o",
|
|
239
|
+
headers = run_curl(["-s", "-D", "-", "-o", os.devnull, "-X", "GET", url])
|
|
240
240
|
payment_needed = parse_payment_needed(headers)
|
|
241
241
|
else:
|
|
242
|
-
curl_args = ["-s", "-D", "-", "-o",
|
|
242
|
+
curl_args = ["-s", "-D", "-", "-o", os.devnull, "-X", method, url]
|
|
243
243
|
if body is not None:
|
|
244
244
|
curl_args.extend(["-H", f"Content-Type: {content_type}", "-d", body])
|
|
245
245
|
headers = run_curl(curl_args)
|
|
@@ -80,6 +80,11 @@ if [ "$MODE" = "summary" ]; then
|
|
|
80
80
|
fi
|
|
81
81
|
case "$PROJECT_PATH" in /*) ;; *) echo "SANDBOX_ERROR:项目路径必须为绝对路径" >&2; exit 2 ;; esac
|
|
82
82
|
[ -d "$PROJECT_PATH" ] && [ ! -L "$PROJECT_PATH" ] || { echo "SANDBOX_ERROR:项目目录不可访问或不安全" >&2; exit 2; }
|
|
83
|
+
if declare -F windows_protect >/dev/null; then
|
|
84
|
+
windows_probe=$(mktemp "${PROJECT_PATH}/.windows-acl-probe.XXXXXX") || exit 78
|
|
85
|
+
windows_protect "$windows_probe" || { rm -f "$windows_probe"; exit 78; }
|
|
86
|
+
rm -f "$windows_probe" || exit 78
|
|
87
|
+
fi
|
|
83
88
|
detected=()
|
|
84
89
|
find "$PROJECT_PATH" -maxdepth 4 -type f \( -name pom.xml -o -name build.gradle -o -name build.gradle.kts \) -print -quit | grep -q . && detected+=(Java)
|
|
85
90
|
find "$PROJECT_PATH" -maxdepth 4 -type f -name package.json -print -quit | grep -q . && detected+=(Node.js)
|
|
@@ -194,6 +199,7 @@ ensure_config_not_tracked() {
|
|
|
194
199
|
}
|
|
195
200
|
|
|
196
201
|
ensure_config_permissions() {
|
|
202
|
+
if declare -F windows_protect >/dev/null; then windows_protect "$CONFIG_PATH"; return $?; fi
|
|
197
203
|
local mode
|
|
198
204
|
chmod 600 "$CONFIG_PATH" 2>/dev/null || return 1
|
|
199
205
|
if mode=$(stat -f '%Lp' "$CONFIG_PATH" 2>/dev/null); then
|
|
@@ -226,7 +232,10 @@ validate_data() {
|
|
|
226
232
|
}
|
|
227
233
|
|
|
228
234
|
render_summary() {
|
|
229
|
-
local data="$1" rows input
|
|
235
|
+
local data="$1" rows input config_display_path="$CONFIG_PATH"
|
|
236
|
+
case "$(uname -s)" in
|
|
237
|
+
MINGW*|MSYS*) config_display_path=$(cygpath -m "$CONFIG_PATH") || return 1 ;;
|
|
238
|
+
esac
|
|
230
239
|
rows=$(echo "$data" | jq -r '
|
|
231
240
|
def safe: tostring|gsub("[|\\r\\n]";" ");
|
|
232
241
|
.appIds[0] as $app |
|
|
@@ -235,7 +244,7 @@ render_summary() {
|
|
|
235
244
|
"| 沙箱买家登录密码 | "+(.sandboxAccounts.user.logonPassword|safe)+" |",
|
|
236
245
|
"| 沙箱买家支付密码 | "+(.sandboxAccounts.user.payPassword|safe)+" |"] | join("\n")
|
|
237
246
|
') || return 1
|
|
238
|
-
input=$(jq -cn --arg productName "$PRODUCT_NAME" --arg configPath "$
|
|
247
|
+
input=$(jq -cn --arg productName "$PRODUCT_NAME" --arg configPath "$config_display_path" --arg environmentRows "$rows" '{productName:$productName,configPath:$configPath,environmentRows:$environmentRows}') || return 1
|
|
239
248
|
printf '%s' "$input" | node "$RENDERER" sandbox.environment.summary --variant DEFAULT || return 1
|
|
240
249
|
printf '%s' '{}' | node "$RENDERER" sandbox.environment.reminder --variant DEFAULT || return 1
|
|
241
250
|
}
|
|
@@ -312,6 +321,7 @@ if [ "$MODE" = "create" ]; then
|
|
|
312
321
|
validate_data "$data" || { echo "SANDBOX_ERROR:候选 data 缺少当前语言或测试账号必含字段" >&2; exit 1; }
|
|
313
322
|
temp=$(mktemp "${PROJECT_PATH}/.alipay-sandbox.XXXXXX") || exit 1
|
|
314
323
|
chmod 600 "$temp" 2>/dev/null || true
|
|
324
|
+
if declare -F windows_protect >/dev/null; then windows_protect "$temp" || { rm -f "$temp"; exit 78; }; fi
|
|
315
325
|
printf '%s\n' "$data" >"$temp" || { rm -f "$temp"; exit 1; }
|
|
316
326
|
mv "$temp" "$CONFIG_PATH" || { rm -f "$temp"; exit 1; }
|
|
317
327
|
ensure_config_permissions || { echo "SANDBOX_ERROR:无法确认配置权限为 0600" >&2; exit 1; }
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
> 本文档定义 alipay-cli 的检测、安装、验证规范,供集成流程和签约流程统一引用。
|
|
4
4
|
|
|
5
|
+
Windows 与其他系统同样先按根启动协议执行 `env refresh-alipay-cli`;Windows 内部通过正式 `https://opengw.alipay.com/alipaycli/install_ps1` PowerShell 安装器刷新 CLI。随后按 [Windows 环境说明](windows-environment.md) 在根意图确定后执行 `windows-entry`;READY 使用 Windows 原生工具和 Git Bash,LEGACY 保留原 Node 独立开发及官网开通分支。Windows 不执行下文 Unix 安装或包管理器兜底链。原生 Node 消息、项目定位和遥测不依赖 Git Bash/jq/CLI;这些工具缺失不得关闭遥测或改变会话身份。
|
|
6
|
+
|
|
5
7
|
---
|
|
6
8
|
|
|
7
9
|
## 1. CLI 检测
|
|
@@ -65,7 +67,7 @@ which alipay-cli 2>/dev/null && alipay-cli version
|
|
|
65
67
|
|
|
66
68
|
## 3. 前置依赖:用户级 jq
|
|
67
69
|
|
|
68
|
-
当前官方 alipay-cli 安装脚本直接下载对应平台二进制,不依赖 GPG/PGP。Skill 不检测、安装或记录 GPG,也不设置跳过 PGP
|
|
70
|
+
当前官方 alipay-cli Unix 安装脚本直接下载对应平台二进制,不依赖 GPG/PGP。Skill 不检测、安装或记录 GPG,也不设置跳过 PGP 的环境变量;下述 Unix 安装命令继续使用 `ALIPAY_CLI_SKIP_VERIFY=true`。Windows 正式 PowerShell 安装命令同样设置该变量,安装后的 EXE 仍需独立启动验证。
|
|
69
71
|
|
|
70
72
|
签约与 Unix/macOS/Linux 快速沙箱仍需 jq,手工验证命令为:
|
|
71
73
|
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
`SESSION_ID` 复用启动器处理声明选择时一次取得的稳定身份,后续采集和业务 runtime 命令均显式携带同一个值。宿主无身份时,启动器的 resolve-session 生成一次随机身份并沿用,不能为对话与业务分别生成。无法恢复身份时重新展示声明并取得选择,不能继承旧会话同意。上传的 `conversation_id` 仍由运行时生成独立随机 UUID,不等于 SESSION_ID 或业务 RUN_ID。
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
首次采集以触发 Skill 的那条用户消息为起点。用户同意采集时,按原始顺序补采授权前的完整对话:触发消息为第一条(sequence=1),随后依次是内测声明、澄清往来(如有)和同意回复,每条只采集一次,不重复采集。授权前的助手收口消息(声明、澄清)与正常轮次一样带 `--final true` 采集;其 `MESSAGE_ID` 由对应用户消息的幂等键确定性派生(如 `<触发幂等键>#notice`、`<澄清回复幂等键>#clarify`),同一对话内不得与其他消息重复。授权前内容无法可靠取得(如上下文压缩)时,从可可靠取得的最早消息开始,禁止伪造。`MESSAGE_ID` 使用消息的稳定非内容型身份,同一消息重试复用。`SANITIZED_MESSAGE_JSON` 是 `{"role":"user","content":"脱敏后的消息","has_attachments":false}`;只替换凭证与个人信息,保留其余文字及格式。原文不得拼入命令或普通临时文件,使用结构化参数安全传递脱敏 JSON。无文字附件用空文本和 true;不读取附件、OCR 或文件名。运行时兼容 `{"text":"..."}`,其余非法结构静默拒绝。
|
|
18
18
|
|
|
19
19
|
```text
|
|
20
20
|
node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" telemetry start-conversation --session-id "<SESSION_ID>" --message-id "$MESSAGE_ID" --message-json "$SANITIZED_MESSAGE_JSON"
|
|
@@ -42,7 +42,7 @@ node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" telemetry opt-out --ses
|
|
|
42
42
|
node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" telemetry conversation-message --session-id "<SESSION_ID>" --conversation-id "$CONVERSATION_ID" --message-id "$MESSAGE_ID" --message-json "$SANITIZED_MESSAGE_JSON"
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
用户暂时离开、等待补材料或审核、澄清、遇到报错或中间阶段完成都不结束采集;之后在同一宿主对话继续时沿用原 conversation_id。自更新后保留当前标识,后续命令使用新版同一路径。产品已明确时,初始化和后续消息命令可追加 `--product-type aipay|webpay|apppay`;未知则省略,d5=UNKNOWN。不读取或关联业务 run
|
|
45
|
+
用户暂时离开、等待补材料或审核、澄清、遇到报错或中间阶段完成都不结束采集;之后在同一宿主对话继续时沿用原 conversation_id。自更新后保留当前标识,后续命令使用新版同一路径。产品已明确时,初始化和后续消息命令可追加 `--product-type aipay|webpay|apppay`;未知则省略,d5=UNKNOWN。不读取或关联业务 run;首次授权前的补采只在上述明确同意后按原始顺序执行,后续持续采集不回填遗漏消息。
|
|
46
46
|
|
|
47
47
|
助手最终收口回复固定采用先采集、后发送:Agent 组织好本轮最终收口回复后,先执行上述 `conversation-message` 并追加 `--final true`,`--message-json` 的 content 必须是随后发送正文的脱敏版本,仅允许替换凭证和个人信息;执行采集后发送原定回复。禁止先发送后采集、发送后补采或在脱敏之外改写采集内容。assistant 角色缺少 `--final true` 时运行时静默丢弃该条记录,过程回复不得调用 conversation-message。采集成功时 stderr 产生唯一 `ALIPAY_AIPAY_INTERNAL:CONVERSATION_MESSAGE_RECORDED=<sequence>` 内部事实行;未出现该 marker 视为采集失败,遥测失败静默、不阻断 Skill,仍正常发送回复。
|
|
48
48
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 完整接入编排
|
|
2
2
|
|
|
3
|
-
本文件是 `full_process`
|
|
3
|
+
本文件是 `full_process` 唯一入口。Windows 复用根入口的 READY/LEGACY 分流,或明确修复后唯一、根意图匹配的新 READY 事实;命令携带当前有效的 `--windows-route`。READY 执行 Integration 快速沙箱及 Onboarding 本地流程,LEGACY 先完成可独立开发内容,再在原衔接点输出站点引导。两者都不重新安装、不创建 Integration Worker。启动方案送达前只复用 Integration 步骤 1 的项目、语言、当前系统分支环境和沙箱准备;不得开发代码、进入 Onboarding 或读取开通信息。
|
|
4
4
|
|
|
5
5
|
目标项目和技术栈确定后执行 `node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" flow integration entry --agent-platform "<AGENT_PLATFORM>" --session-id "<SESSION_ID>"`,只加载当前入口阶段并按步骤 1/2 准备及展示方案;代码开发满足衔接条件后执行 `node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" flow onboarding entry --agent-platform "<AGENT_PLATFORM>" --session-id "<SESSION_ID>"`。禁止整读两个 flow。所有 Skill 自有运行时动作只用当前 Skill 绝对路径下的统一入口单命令执行,不前置 `cd`、不拼接管道;用户项目命令仍以已确认项目根为 workdir。
|
|
6
6
|
|
|
@@ -52,7 +52,7 @@ node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" integration-message pro
|
|
|
52
52
|
- `NO_PAYMENT`:无支付能力。
|
|
53
53
|
- `STATUS_UNKNOWN`:不可访问、证据冲突/不足或产品不明,停止。
|
|
54
54
|
|
|
55
|
-
合法项目分类与前三种代码状态确认后进入 Integration;`PROJECT_UNRESOLVED/STATUS_UNKNOWN` 继续澄清。Unix/macOS/Linux 的 `CREATE_PENDING|VERIFY_PENDING` 和 Windows 的 `VERIFY_PENDING` 都不阻止扫描/开发。新项目保留 `projectOriginLabel=本轮新建项目`;已有项目“新建”只能新增能力或使用空路径。这些分类只用于本轮分流,不持久化。
|
|
55
|
+
合法项目分类与前三种代码状态确认后进入 Integration;`PROJECT_UNRESOLVED/STATUS_UNKNOWN` 继续澄清。Unix/macOS/Linux 的 `CREATE_PENDING|VERIFY_PENDING` 和 Windows READY 的 `CREATE_PENDING|VERIFY_PENDING`、Windows LEGACY 的 `VERIFY_PENDING` 都不阻止扫描/开发。新项目保留 `projectOriginLabel=本轮新建项目`;已有项目“新建”只能新增能力或使用空路径。这些分类只用于本轮分流,不持久化。
|
|
56
56
|
|
|
57
57
|
## 完整接入启动方案
|
|
58
58
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"schemaVersion":1,"rules":[{"policyId":"P-MCP-CONTRACT-FROZEN","scope":"all","severity":"critical","text":"只用当前 Skill 已验证的 MCP 脚本契约;禁止推断、改名或尝试近似方法。","runtimeText":"仅用已验证脚本;禁推断或尝试近似方法。"},{"policyId":"P-AUTH-BEFORE-ONBOARDING","scope":"onboarding","severity":"critical","text":"登录、scope 和 MCC 校验通过前,禁止 onboarding 查询或写入。","runtimeText":"登录/scope/MCC 未通过前禁查询和写入。"},{"policyId":"P-SIGNING-WRITE","scope":"onboarding.signing","severity":"critical","text":"签约材料校验通过后直接提交,不增加确认;缺失或非法时禁止提交。"},{"policyId":"P-SERVICE-WRITE","scope":"onboarding.service","severity":"critical","text":"服务创建摘要送达后直接创建;服务修改须取得绑定当前脱敏摘要的明确确认。"},{"policyId":"P-APPLICATION-WRITE","scope":"onboarding.application","severity":"critical","text":"完整新建材料或非空候选后的明确“新建”已构成创建确认;快照未变时不追加确认,公钥确认后直接提审。"},{"policyId":"P-WRITE-UNKNOWN","scope":"onboarding.write","severity":"critical","text":"非幂等写入结果不明时只读核验;仍无法确认则进入 UNKNOWN,禁止重试写入。"},{"policyId":"P-PARTIAL-RESULT","scope":"onboarding","severity":"critical","text":"签约、服务、应用分支独立记录,失败不回滚或覆盖其他成功结果。"},{"policyId":"P-MATERIAL-CATEGORY","scope":"onboarding.materials","severity":"required","text":"每轮只展示一个材料类别;同类一次收齐,已提供材料不得重复索取。"},{"policyId":"P-KEY-NO-PRIVATE","scope":"onboarding.application","severity":"critical","text":"Agent 禁止请求、读取、处理、保存或输出生产私钥,也不提供密钥生成命令;仅用户选择方案3后可打开本地静态页面,由用户在浏览器内自行生成并保存密钥,禁止 Agent 操作页面生成按钮或读取页面密钥。"},{"policyId":"P-KEY-PUBLIC-USER","scope":"onboarding.application","severity":"critical","text":"应用公钥只能由用户提供;缺少时禁止 createKeyConfirmPage,也不得补全、改写或添加 PEM 头尾。"},{"policyId":"P-AUTH-URL","scope":"onboarding.authorization","severity":"critical","text":"授权链接只由 auth.sh 构造并校验固定域名、路径和参数;禁用 verification_url。"},{"policyId":"P-KEY-URL","scope":"onboarding.application","severity":"critical","text":"公钥确认只展示 createKeyConfirmPage 返回并校验的裸 URL;禁止二维码链接和 alipays://。"},{"policyId":"P-AUTH-URL-AUTO-OPEN","scope":"onboarding.authorization","severity":"critical","text":"授权 URL 交付后调用受控 opener;失败时保留同一裸 URL 和复制兜底。"},{"policyId":"P-KEY-URL-AUTO-OPEN","scope":"onboarding.application","severity":"critical","text":"公钥 URL 交付后调用受控 opener;失败时保留同一裸 URL 和复制兜底。"},{"policyId":"P-KEY-TOOL-DOWNLOAD","scope":"onboarding.application","severity":"critical","text":"预发版查询应用列表成功后展示三种公钥获取方式,不自动下载密钥工具。用户明确选择方案3才打开随包本地离线页面;失败引导自行下载安装官方密钥工具。页面由用户自行生成、保存密钥,Agent 只接收用户提供的公钥。"},{"policyId":"P-A2M-SANDBOX","scope":"integration.aipay","severity":"critical","text":"AI 按量付费沙箱 serviceId 固定为 api_mock_service_id,SDK 使用沙箱网关;生产网关和真实 serviceId 只用于正式配置。","runtimeText":"A2M 沙箱固定 api_mock_service_id 与沙箱网关;生产值仅用于正式配置。"},{"policyId":"P-A2M-SUCCESS","scope":"integration.aipay","severity":"critical","text":"自动联调只有在 HTTP 200、非空可归属资源、无明确业务失败且适用 Payment-Validation 有效时通过。","runtimeText":"联调仅在 HTTP 200、资源可归属、无业务失败且适用回执有效时通过。"},{"policyId":"P-SANDBOX-CREDENTIAL-EXCEPTION","scope":"integration.sandbox","severity":"critical","text":"Unix/macOS/Linux
|
|
1
|
+
{"schemaVersion":1,"rules":[{"policyId":"P-MCP-CONTRACT-FROZEN","scope":"all","severity":"critical","text":"只用当前 Skill 已验证的 MCP 脚本契约;禁止推断、改名或尝试近似方法。","runtimeText":"仅用已验证脚本;禁推断或尝试近似方法。"},{"policyId":"P-AUTH-BEFORE-ONBOARDING","scope":"onboarding","severity":"critical","text":"登录、scope 和 MCC 校验通过前,禁止 onboarding 查询或写入。","runtimeText":"登录/scope/MCC 未通过前禁查询和写入。"},{"policyId":"P-SIGNING-WRITE","scope":"onboarding.signing","severity":"critical","text":"签约材料校验通过后直接提交,不增加确认;缺失或非法时禁止提交。"},{"policyId":"P-SERVICE-WRITE","scope":"onboarding.service","severity":"critical","text":"服务创建摘要送达后直接创建;服务修改须取得绑定当前脱敏摘要的明确确认。"},{"policyId":"P-APPLICATION-WRITE","scope":"onboarding.application","severity":"critical","text":"完整新建材料或非空候选后的明确“新建”已构成创建确认;快照未变时不追加确认,公钥确认后直接提审。"},{"policyId":"P-WRITE-UNKNOWN","scope":"onboarding.write","severity":"critical","text":"非幂等写入结果不明时只读核验;仍无法确认则进入 UNKNOWN,禁止重试写入。"},{"policyId":"P-PARTIAL-RESULT","scope":"onboarding","severity":"critical","text":"签约、服务、应用分支独立记录,失败不回滚或覆盖其他成功结果。"},{"policyId":"P-MATERIAL-CATEGORY","scope":"onboarding.materials","severity":"required","text":"每轮只展示一个材料类别;同类一次收齐,已提供材料不得重复索取。"},{"policyId":"P-KEY-NO-PRIVATE","scope":"onboarding.application","severity":"critical","text":"Agent 禁止请求、读取、处理、保存或输出生产私钥,也不提供密钥生成命令;仅用户选择方案3后可打开本地静态页面,由用户在浏览器内自行生成并保存密钥,禁止 Agent 操作页面生成按钮或读取页面密钥。"},{"policyId":"P-KEY-PUBLIC-USER","scope":"onboarding.application","severity":"critical","text":"应用公钥只能由用户提供;缺少时禁止 createKeyConfirmPage,也不得补全、改写或添加 PEM 头尾。"},{"policyId":"P-AUTH-URL","scope":"onboarding.authorization","severity":"critical","text":"授权链接只由 auth.sh 构造并校验固定域名、路径和参数;禁用 verification_url。"},{"policyId":"P-KEY-URL","scope":"onboarding.application","severity":"critical","text":"公钥确认只展示 createKeyConfirmPage 返回并校验的裸 URL;禁止二维码链接和 alipays://。"},{"policyId":"P-AUTH-URL-AUTO-OPEN","scope":"onboarding.authorization","severity":"critical","text":"授权 URL 交付后调用受控 opener;失败时保留同一裸 URL 和复制兜底。"},{"policyId":"P-KEY-URL-AUTO-OPEN","scope":"onboarding.application","severity":"critical","text":"公钥 URL 交付后调用受控 opener;失败时保留同一裸 URL 和复制兜底。"},{"policyId":"P-KEY-TOOL-DOWNLOAD","scope":"onboarding.application","severity":"critical","text":"预发版查询应用列表成功后展示三种公钥获取方式,不自动下载密钥工具。用户明确选择方案3才打开随包本地离线页面;失败引导自行下载安装官方密钥工具。页面由用户自行生成、保存密钥,Agent 只接收用户提供的公钥。"},{"policyId":"P-A2M-SANDBOX","scope":"integration.aipay","severity":"critical","text":"AI 按量付费沙箱 serviceId 固定为 api_mock_service_id,SDK 使用沙箱网关;生产网关和真实 serviceId 只用于正式配置。","runtimeText":"A2M 沙箱固定 api_mock_service_id 与沙箱网关;生产值仅用于正式配置。"},{"policyId":"P-A2M-SUCCESS","scope":"integration.aipay","severity":"critical","text":"自动联调只有在 HTTP 200、非空可归属资源、无明确业务失败且适用 Payment-Validation 有效时通过。","runtimeText":"联调仅在 HTTP 200、资源可归属、无业务失败且适用回执有效时通过。"},{"policyId":"P-SANDBOX-CREDENTIAL-EXCEPTION","scope":"integration.sandbox","severity":"critical","text":"Unix/macOS/Linux 与 Windows READY 只允许快速沙箱实际返回且已校验的买家登录/支付密码在登记的沙箱摘要和付款体验中经 stdin 临时渲染。Windows READY 的快速沙箱配置须写入当前项目受保护的本机文件;Windows LEGACY 手工沙箱允许用户在 sandbox.windows.manual_setup 后提供当前沙箱应用的 APPID、支付宝公钥、应用公钥、与当前开发语言匹配的应用私钥和沙箱账号信息;Agent 只能将其用于已确认目标项目的受保护配置,不得在回复、摘要、普通日志或业务状态中复述或另存原文。两类例外均不得扩展到生产环境账号、应用私钥或密码。","runtimeText":"Unix/macOS/Linux 与 Windows READY 已校验快速沙箱买家密码仅限登记摘要/付款体验;Windows LEGACY 手工资料仅入受保护项目配置,禁复述、另存或扩展到生产值。"},{"policyId":"P-SENSITIVE-STATE","scope":"all","severity":"critical","text":"用户公钥仅用于当前 app key/verify-key/verify-key-and-audit 调用,禁止在回复、摘要、普通日志、跨会话状态或宽权限临时文件中复述或保存;除登记的沙箱例外外,私钥、token、Payment-Proof、签名串、完整支付表单和未脱敏响应同样不得进入这些位置;临时 URL 仅可由登记动作校验后在该动作正文展示。","runtimeText":"公钥限当前 app 调用且禁复述/保存;敏感值禁入回复/摘要/日志/状态/宽权限文件;临时 URL 仅由登记动作展示。"},{"policyId":"P-PROJECT-PROTECT","scope":"integration","severity":"critical","text":"不得清空、覆盖或删除用户既有项目;只在已确认目标路径和范围内做必要修改。","runtimeText":"禁清空/覆盖/删除既有项目;仅改已确认路径和范围。"},{"policyId":"P-CUSTOMER-OUTPUT-EXCLUSIVE","scope":"all","severity":"critical","text":"登记 runner/script 的 stdout 是唯一对客正文,禁止增删改写;阻塞消息送达后立即等待用户。","runtimeText":"登记 stdout 原文是唯一正文;阻塞送达后立即等待。"},{"policyId":"P-ONBOARDING-CONTROL-CHANNEL","scope":"onboarding","severity":"critical","text":"剔除 ALIPAY_AIPAY_INTERNAL 内部行后再处理 stdout;内部行禁止对客,正文为空时直接转移。","runtimeText":"内部行禁对客;正文为空按唯一终态转移。"},{"policyId":"P-AUTH-PAGE-DELIVERY-BARRIER","scope":"onboarding.authorization","severity":"critical","text":"`auth.page` stdout 必须先独立送达,再 opener 和有限轮询;不得合并 pending 或收口,也不等待确认。"},{"policyId":"P-KEY-PAGE-DELIVERY-BARRIER","scope":"onboarding.application","severity":"critical","text":"`application.key.page` stdout 必须先独立送达,再 opener 和有限轮询;不得合并 pending 或收口,也不等待确认。"},{"policyId":"P-DETERMINISTIC-HANDOFF","scope":"all","severity":"critical","text":"只执行 flow 动作处登记命令并按唯一终态立即转移;禁止追加命令重复解析,失败只走登记恢复。","runtimeText":"仅执行登记命令并按唯一终态转移;禁追加解析;失败只走登记恢复。"}],"officialUrls":{"aipaySite":"https://aipay.alipay.com/","aipaySkillSite":"https://aipay.alipay.com/?from=alipay-aipay-skill","merchantPlatform":"https://b.alipay.com/page/portal/home","openPlatform":"https://open.alipay.com/","openPlatformHome":"https://open.alipay.com","technicalSupport":"https://opensupport.alipay.com/support/intelligent-services?form=payskill","keyToolManual":"https://opendocs.alipay.com/isv/02kipk","keyToolMac":"https://ideservice.alipay.com/ide/getPluginUrl.htm?clientType=assistant&platform=mac&channelType=WEB","keyToolWindows":"https://ideservice.alipay.com/ide/getPluginUrl.htm?clientType=assistant&platform=win&channelType=WEB","androidSandboxAlipay":"https://mdn.alipayobjects.com/sandboxsys/afts/img/_itHRrdOD9oAAAAAAAAAAAAADgSLAQBr/original","sandboxToolFallback":"https://open.alipay.com/develop/sandbox/tool","sandboxGateway":"https://openapi-sandbox.dl.alipaydev.com/gateway.do","productionGateway":"https://openapi.alipay.com/gateway.do","openPlatformPaySkill":"https://open.alipay.com?form=payskill","traditionalPaymentSkill":"https://github.com/alipay/ai/tree/main/skills","dingtalkSupportGroupQr":"https://mdn.alipayobjects.com/huamei_5fajmi/afts/img/MlFpRKmYyLIAAAAARJAAAAgADlahAQFr/original","wecomCommunityGroupQr":"https://mdn.alipayobjects.com/huamei_5fajmi/afts/img/Cz0TTZVO7_4AAAAAQDAAAAgADlahAQFr/fmt.webp","applicationKeyFormat":"https://opendocs.alipay.com/common/055l5k"},"authorizationProducts":[{"productName":"AI 按量付费","salesCode":"I1080300001000160457","scope":"app:all,machine_pay:write,agmnt:write"},{"productName":"AI 网页应用收款","salesCode":"I1080300001000041203","scope":"app:all,fast_instant_trade_pay:write"},{"productName":"AI 移动应用收款","salesCode":"I1080300001000041313","scope":"app:all,auth_alipay_apppay:write"}],"temporaryUrlAllowlist":{"authorization":{"host":"aipay.alipay.com","path":"/cli-auth","requiredQueryParams":["deviceCode","productCode","mccCode"],"optionalQueryParams":["platform"]},"publicKeyConfirmation":[{"host":"aipay.alipay.com","path":"/public-key-confirm","requiredQueryParams":["keyConfirmToken"],"optionalQueryParams":[]},{"host":"open.alipay.com","path":"/ai/ai-resource-center/public-key-confirm","requiredQueryParams":["keyConfirmToken"],"optionalQueryParams":[]}],"windowsOnboardingRedirect":{"host":"aipay.alipay.com","path":"/","requiredQueryParams":["from","reason","platform_id"],"optionalQueryParams":[]}}}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
const windowsEnvironmentRunner = process.platform === 'win32'
|
|
4
|
+
? (await import('./windows/prepare.mjs')).runEnvironment
|
|
5
|
+
: null;
|
|
6
|
+
|
|
3
7
|
import process from 'node:process';
|
|
4
8
|
import path from 'node:path';
|
|
5
9
|
import { fileURLToPath } from 'node:url';
|
|
@@ -7,6 +11,11 @@ import { fileURLToPath } from 'node:url';
|
|
|
7
11
|
import { checkCliEnvironment, isWindowsPlatform } from './platform_compat.mjs';
|
|
8
12
|
|
|
9
13
|
export function runAlipayCliEnvCli(argv = process.argv) {
|
|
14
|
+
if (windowsEnvironmentRunner && !(argv[2] === 'integration-check' && process.env.ALIPAY_AIPAY_WINDOWS_ROUTE === 'LEGACY')) {
|
|
15
|
+
process.exitCode = windowsEnvironmentRunner(argv.slice(2));
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
10
19
|
const mode = argv[2];
|
|
11
20
|
if (!['check', 'integration-check'].includes(mode) || argv.length !== 3) {
|
|
12
21
|
console.error('用法: node alipay_cli_env.mjs <check|integration-check>');
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
const windowsCliRefresh = process.platform === 'win32'
|
|
4
|
+
? (await import('./windows/cli-install.mjs')).refreshWindowsCli
|
|
5
|
+
: null;
|
|
6
|
+
|
|
3
7
|
import { spawnSync } from 'node:child_process';
|
|
4
8
|
import fs from 'node:fs';
|
|
5
9
|
import os from 'node:os';
|
|
@@ -54,7 +58,7 @@ function commandOutput(result) {
|
|
|
54
58
|
}
|
|
55
59
|
|
|
56
60
|
function verifyAlipayCli(binDir) {
|
|
57
|
-
const command = path.join(binDir, process.platform === 'win32' ? 'alipay-cli.
|
|
61
|
+
const command = path.join(binDir, process.platform === 'win32' ? 'alipay-cli.exe' : 'alipay-cli');
|
|
58
62
|
const result = spawnSync(command, ['version'], {
|
|
59
63
|
encoding: 'utf8',
|
|
60
64
|
env: cleanChildEnv({ PATH: `${binDir}${path.delimiter}${process.env.PATH || ''}` }),
|
|
@@ -72,6 +76,11 @@ export function runAlipayCliRefreshCli(argv = process.argv) {
|
|
|
72
76
|
return;
|
|
73
77
|
}
|
|
74
78
|
|
|
79
|
+
if (windowsCliRefresh) {
|
|
80
|
+
emit(windowsCliRefresh());
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
75
84
|
const home = homeDir();
|
|
76
85
|
if (!home) {
|
|
77
86
|
emit('FAILED');
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { spawnSync as nativeSpawn } from 'node:child_process';
|
|
4
|
+
const { spawnSync } = process.platform === 'win32'
|
|
5
|
+
? await import('./windows/execution.mjs')
|
|
6
|
+
: { spawnSync: nativeSpawn };
|
|
4
7
|
import process from 'node:process';
|
|
5
8
|
|
|
6
9
|
const internalPrefix = 'ALIPAY_AIPAY_INTERNAL:';
|
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
# 调用前置: 无
|
|
6
6
|
#=============================================================================
|
|
7
7
|
|
|
8
|
+
case "$(uname -s)" in
|
|
9
|
+
MINGW*|MSYS*) source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/windows/shell_helpers.sh" || exit 78 ;;
|
|
10
|
+
esac
|
|
11
|
+
|
|
8
12
|
case "${HOME:-}" in
|
|
9
13
|
/*)
|
|
10
14
|
user_bin="$HOME/.local/bin"
|
|
@@ -39,6 +43,9 @@ ALIPAY_AIPAY_LOCAL_CONFIG_PERMISSION_EXIT_CODE=77
|
|
|
39
43
|
ALIPAY_AIPAY_LOCAL_CONFIG_ACCESS_CONFIRMED=false
|
|
40
44
|
|
|
41
45
|
alipay_cli_credentials_dir() {
|
|
46
|
+
case "$(uname -s)" in
|
|
47
|
+
MINGW*|MSYS*) cygpath -u "$ALIPAY_WINDOWS_CREDENTIALS_DIR"; return $? ;;
|
|
48
|
+
esac
|
|
42
49
|
case "${HOME:-}" in
|
|
43
50
|
/*) [ "$HOME" != "/" ] || return "$ALIPAY_CLI_LOCAL_STATE_PERMISSION_EXIT_CODE" ;;
|
|
44
51
|
*) return "$ALIPAY_CLI_LOCAL_STATE_PERMISSION_EXIT_CODE" ;;
|
|
@@ -47,6 +54,9 @@ alipay_cli_credentials_dir() {
|
|
|
47
54
|
}
|
|
48
55
|
|
|
49
56
|
alipay_cli_logs_dir() {
|
|
57
|
+
case "$(uname -s)" in
|
|
58
|
+
MINGW*|MSYS*) cygpath -u "$ALIPAY_WINDOWS_LOGS_DIR"; return $? ;;
|
|
59
|
+
esac
|
|
50
60
|
local data_home="${XDG_DATA_HOME:-}"
|
|
51
61
|
if [ -z "$data_home" ]; then
|
|
52
62
|
case "${HOME:-}" in
|
|
@@ -67,7 +77,7 @@ alipay_cli_has_local_state_permission_error() {
|
|
|
67
77
|
[ -n "$raw" ] || return 1
|
|
68
78
|
|
|
69
79
|
permission_pattern='permission denied|operation not permitted|(^|[^[:alnum:]_])(EACCES|EPERM)([^[:alnum:]_]|$)'
|
|
70
|
-
private_state_pattern='poll_state\.enc\.tmp|session\.enc|\.alipay-cli[/\\]credentials|alipay-cli[/\\]logs'
|
|
80
|
+
private_state_pattern='poll_state\.enc\.tmp|session\.enc|\.alipay-cli[/\\]credentials|alipay-cli[/\\](data[/\\])?logs'
|
|
71
81
|
local_state_failure_pattern='写入临时文件失败|删除凭据文件失败|can.?t rename log file'
|
|
72
82
|
|
|
73
83
|
printf '%s' "$raw" | grep -qiE "$local_state_failure_pattern" && return 0
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { spawn } from 'node:child_process';
|
|
3
|
+
import { spawn as nativeSpawn } from 'node:child_process';
|
|
4
|
+
const { spawn } = process.platform === 'win32'
|
|
5
|
+
? await import('./windows/execution.mjs')
|
|
6
|
+
: { spawn: nativeSpawn };
|
|
4
7
|
import path from 'node:path';
|
|
5
8
|
import process from 'node:process';
|
|
6
9
|
import { fileURLToPath } from 'node:url';
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
const windowsRouting = process.platform === 'win32' ? await import('./windows/routing.mjs') : null;
|
|
5
|
+
let windowsMccCatalog;
|
|
6
|
+
|
|
3
7
|
import { createHash } from 'node:crypto';
|
|
4
8
|
import path from 'node:path';
|
|
5
9
|
import process from 'node:process';
|
|
@@ -156,6 +160,7 @@ async function readStdin() {
|
|
|
156
160
|
}
|
|
157
161
|
|
|
158
162
|
function runPlatformEntry(args = {}) {
|
|
163
|
+
if (windowsRouting && windowsRouting.onboardingRoute() === 'READY') return '';
|
|
159
164
|
if (!isWindowsPlatform()) return '';
|
|
160
165
|
const runContext = currentRunContext();
|
|
161
166
|
if (runContext?.terminal) {
|
|
@@ -167,7 +172,7 @@ function runPlatformEntry(args = {}) {
|
|
|
167
172
|
}
|
|
168
173
|
const platformId = platformIdFromEnv(process.env)
|
|
169
174
|
|| runContext?.run_id
|
|
170
|
-
||
|
|
175
|
+
|| sessionPlatformId(process.env);
|
|
171
176
|
if (!platformId) {
|
|
172
177
|
throw new Error('Windows 产品开通引导缺少有效的当前 Onboarding run context');
|
|
173
178
|
}
|
|
@@ -176,6 +181,12 @@ function runPlatformEntry(args = {}) {
|
|
|
176
181
|
});
|
|
177
182
|
}
|
|
178
183
|
|
|
184
|
+
function sessionPlatformId(env = process.env) {
|
|
185
|
+
const session = env.ALIPAY_AIPAY_SESSION_ID;
|
|
186
|
+
return typeof session === 'string' && session && !/[\u0000-\u001f\u007f,^=]/u.test(session)
|
|
187
|
+
? `session_${createHash('sha256').update(session).digest('hex').slice(0, 32)}` : '';
|
|
188
|
+
}
|
|
189
|
+
|
|
179
190
|
function platformIdFromEnv(env = process.env) {
|
|
180
191
|
const candidate = env.COZE_PROJECT_ID
|
|
181
192
|
|| env.MEOO_PROJECT_ID
|
|
@@ -305,6 +316,10 @@ function mccCandidateFromRecord(record, productType = '', mccRunContext = captur
|
|
|
305
316
|
}
|
|
306
317
|
|
|
307
318
|
function dynamicMccRecordsFromCatalog(rawCatalog) {
|
|
319
|
+
if (windowsRouting && rawCatalog === '@windows-stdin') {
|
|
320
|
+
windowsMccCatalog ??= fs.readFileSync(0, 'utf8');
|
|
321
|
+
rawCatalog = windowsMccCatalog;
|
|
322
|
+
}
|
|
308
323
|
let catalog;
|
|
309
324
|
try {
|
|
310
325
|
catalog = typeof rawCatalog === 'string' ? JSON.parse(rawCatalog) : rawCatalog;
|
|
@@ -1332,7 +1347,7 @@ export async function runOnboardingMessageCli(argv = process.argv) {
|
|
|
1332
1347
|
if (command === 'platform-entry') {
|
|
1333
1348
|
const message = runPlatformEntry(args);
|
|
1334
1349
|
if (message) console.log(message);
|
|
1335
|
-
return;
|
|
1350
|
+
return windowsRouting ? (message ? 'LEGACY' : 'READY') : undefined;
|
|
1336
1351
|
}
|
|
1337
1352
|
if (command === 'product-clarify') {
|
|
1338
1353
|
console.log(runProductClarify());
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { spawnSync as nativeSpawn } from 'node:child_process';
|
|
4
|
+
const { spawnSync } = process.platform === 'win32'
|
|
5
|
+
? await import('./windows/execution.mjs')
|
|
6
|
+
: { spawnSync: nativeSpawn };
|
|
4
7
|
import path from 'node:path';
|
|
5
8
|
import process from 'node:process';
|
|
6
9
|
import { fileURLToPath } from 'node:url';
|