@alipay/alipay-aipay 1.7.0 → 1.7.1
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/README.md +30 -0
- package/dist/commands/install-current.js +15 -7
- package/dist/commands/install.js +20 -16
- package/dist/commands/uninstall.js +8 -3
- package/dist/commands/update.js +34 -16
- package/dist/index.js +10 -4
- package/dist/utils/channels.js +67 -0
- package/dist/utils/config.js +15 -11
- package/dist/utils/file.js +23 -10
- package/dist/utils/npm.js +19 -33
- package/package.json +8 -3
- package/skill/SKILL.md +2 -0
- package/skill/references/normal/json/release-channel.json +1 -0
- package/skill/references/normal/scripts/self_update.mjs +62 -17
- package/skill/references/normal/self-update.md +3 -1
- package/skill-pre/SKILL.md +65 -0
- package/skill-pre/VERSION +1 -0
- package/skill-pre/references/integration/flow.md +602 -0
- package/skill-pre/references/integration/modules/alipay-sdk-reminder.md +281 -0
- package/skill-pre/references/integration/modules/checklist.md +154 -0
- package/skill-pre/references/integration/modules/code-examples/csharp/1-/351/200/232/347/224/250/346/216/245/345/217/243//345/274/202/346/255/245/351/200/232/347/237/245/345/244/204/347/220/206/344/273/243/347/240/201/347/244/272/344/276/213.md +199 -0
- package/skill-pre/references/integration/modules/code-examples/csharp/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/345/205/263/351/227/255/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +68 -0
- package/skill-pre/references/integration/modules/code-examples/csharp/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +83 -0
- package/skill-pre/references/integration/modules/code-examples/csharp/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +80 -0
- package/skill-pre/references/integration/modules/code-examples/csharp/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +73 -0
- package/skill-pre/references/integration/modules/code-examples/csharp/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +62 -0
- package/skill-pre/references/integration/modules/code-examples/csharp/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +132 -0
- package/skill-pre/references/integration/modules/code-examples/csharp/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.md +640 -0
- package/skill-pre/references/integration/modules/code-examples/java/1-/351/200/232/347/224/250/346/216/245/345/217/243//345/274/202/346/255/245/351/200/232/347/237/245/345/244/204/347/220/206/344/273/243/347/240/201/347/244/272/344/276/213.md +184 -0
- package/skill-pre/references/integration/modules/code-examples/java/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/345/205/263/351/227/255/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +72 -0
- package/skill-pre/references/integration/modules/code-examples/java/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +96 -0
- package/skill-pre/references/integration/modules/code-examples/java/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +81 -0
- package/skill-pre/references/integration/modules/code-examples/java/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +77 -0
- package/skill-pre/references/integration/modules/code-examples/java/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +69 -0
- package/skill-pre/references/integration/modules/code-examples/java/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +138 -0
- package/skill-pre/references/integration/modules/code-examples/java/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemoController.md +623 -0
- package/skill-pre/references/integration/modules/code-examples/nodejs/1-/351/200/232/347/224/250/346/216/245/345/217/243//345/274/202/346/255/245/351/200/232/347/237/245/345/244/204/347/220/206/344/273/243/347/240/201/347/244/272/344/276/213.md +135 -0
- package/skill-pre/references/integration/modules/code-examples/nodejs/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/345/205/263/351/227/255/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +51 -0
- package/skill-pre/references/integration/modules/code-examples/nodejs/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +63 -0
- package/skill-pre/references/integration/modules/code-examples/nodejs/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +59 -0
- package/skill-pre/references/integration/modules/code-examples/nodejs/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +54 -0
- package/skill-pre/references/integration/modules/code-examples/nodejs/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +84 -0
- package/skill-pre/references/integration/modules/code-examples/nodejs/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +71 -0
- package/skill-pre/references/integration/modules/code-examples/nodejs/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.md +498 -0
- package/skill-pre/references/integration/modules/code-examples/php/1-/351/200/232/347/224/250/346/216/245/345/217/243//345/274/202/346/255/245/351/200/232/347/237/245/345/244/204/347/220/206/344/273/243/347/240/201/347/244/272/344/276/213.md +157 -0
- package/skill-pre/references/integration/modules/code-examples/php/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/345/205/263/351/227/255/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +59 -0
- package/skill-pre/references/integration/modules/code-examples/php/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +73 -0
- package/skill-pre/references/integration/modules/code-examples/php/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +69 -0
- package/skill-pre/references/integration/modules/code-examples/php/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +65 -0
- package/skill-pre/references/integration/modules/code-examples/php/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +59 -0
- package/skill-pre/references/integration/modules/code-examples/php/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +110 -0
- package/skill-pre/references/integration/modules/code-examples/php/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.md +806 -0
- package/skill-pre/references/integration/modules/code-examples/python/1-/351/200/232/347/224/250/346/216/245/345/217/243//345/274/202/346/255/245/351/200/232/347/237/245/345/244/204/347/220/206/344/273/243/347/240/201/347/244/272/344/276/213.md +128 -0
- package/skill-pre/references/integration/modules/code-examples/python/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/345/205/263/351/227/255/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +57 -0
- package/skill-pre/references/integration/modules/code-examples/python/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +70 -0
- package/skill-pre/references/integration/modules/code-examples/python/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +65 -0
- package/skill-pre/references/integration/modules/code-examples/python/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +62 -0
- package/skill-pre/references/integration/modules/code-examples/python/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +51 -0
- package/skill-pre/references/integration/modules/code-examples/python/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +47 -0
- package/skill-pre/references/integration/modules/code-examples/python/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.md +541 -0
- package/skill-pre/references/integration/modules/interface-contract/aipay-interface-contract.md +52 -0
- package/skill-pre/references/integration/modules/interface-contract/apppay-interface-contract.md +45 -0
- package/skill-pre/references/integration/modules/interface-contract/common-trade-contract.md +42 -0
- package/skill-pre/references/integration/modules/interface-contract/notify-url-contract.md +68 -0
- package/skill-pre/references/integration/modules/interface-contract/webpay-interface-contract.md +44 -0
- package/skill-pre/references/integration/modules/interface-guide.md +61 -0
- package/skill-pre/references/integration/modules/product-decision.md +73 -0
- package/skill-pre/references/integration/modules/sandbox/a2m-sandbox-test.md +235 -0
- package/skill-pre/references/integration/modules/sandbox/alipay-sandbox-tool.md +142 -0
- package/skill-pre/references/integration/modules/sandbox/sandbox-setup-guide.md +239 -0
- package/skill-pre/references/integration/modules/scripts/local_402_sandbox_pay.py +900 -0
- package/skill-pre/references/integration/modules/scripts/sandbox_config.sh +347 -0
- package/skill-pre/references/integration/modules/troubleshooting-flow.md +28 -0
- package/skill-pre/references/normal/alipay-cli-env.md +169 -0
- package/skill-pre/references/normal/conversation-telemetry.md +101 -0
- package/skill-pre/references/normal/full-process-routing.md +92 -0
- package/skill-pre/references/normal/integration-worker.md +90 -0
- package/skill-pre/references/normal/json/customer-messages.json +1 -0
- package/skill-pre/references/normal/json/managed-jq-assets.json +1 -0
- package/skill-pre/references/normal/json/policy-rules.json +1 -0
- package/skill-pre/references/normal/json/release-channel.json +1 -0
- package/skill-pre/references/normal/rejection-guide.md +41 -0
- package/skill-pre/references/normal/scripts/agent_platform.mjs +43 -0
- package/skill-pre/references/normal/scripts/alipay_cli_env.mjs +34 -0
- package/skill-pre/references/normal/scripts/alipay_cli_env.sh +55 -0
- package/skill-pre/references/normal/scripts/alipay_cli_refresh.mjs +129 -0
- package/skill-pre/references/normal/scripts/auth_runtime_runner.mjs +60 -0
- package/skill-pre/references/normal/scripts/checklist_sections.mjs +43 -0
- package/skill-pre/references/normal/scripts/common.sh +365 -0
- package/skill-pre/references/normal/scripts/conversation_telemetry.mjs +105 -0
- package/skill-pre/references/normal/scripts/detect_dev_tool.sh +79 -0
- package/skill-pre/references/normal/scripts/flow_loader.mjs +237 -0
- package/skill-pre/references/normal/scripts/integration_context_runner.mjs +151 -0
- package/skill-pre/references/normal/scripts/integration_message_runner.mjs +1456 -0
- package/skill-pre/references/normal/scripts/interaction_reply.mjs +140 -0
- package/skill-pre/references/normal/scripts/managed_jq.mjs +215 -0
- package/skill-pre/references/normal/scripts/onboarding_discovery_runner.mjs +387 -0
- package/skill-pre/references/normal/scripts/onboarding_message_runner.mjs +1425 -0
- package/skill-pre/references/normal/scripts/onboarding_recovery_runner.mjs +100 -0
- package/skill-pre/references/normal/scripts/open_official_url.sh +205 -0
- package/skill-pre/references/normal/scripts/platform_compat.mjs +42 -0
- package/skill-pre/references/normal/scripts/preview_runtime.mjs +151 -0
- package/skill-pre/references/normal/scripts/project_route_inspector.sh +132 -0
- package/skill-pre/references/normal/scripts/python_script_runner.mjs +58 -0
- package/skill-pre/references/normal/scripts/render_customer_message.mjs +1792 -0
- package/skill-pre/references/normal/scripts/runtime.mjs +271 -0
- package/skill-pre/references/normal/scripts/self_update.mjs +376 -0
- package/skill-pre/references/normal/scripts/telemetry.mjs +2102 -0
- package/skill-pre/references/normal/self-update.md +7 -0
- package/skill-pre/references/normal/telemetry.md +70 -0
- package/skill-pre/references/onboarding/assets/keygen.html +926 -0
- package/skill-pre/references/onboarding/flow.md +595 -0
- package/skill-pre/references/onboarding/modules/app-release.md +90 -0
- package/skill-pre/references/onboarding/modules/authorization.md +43 -0
- package/skill-pre/references/onboarding/modules/error-handling.md +62 -0
- package/skill-pre/references/onboarding/modules/product-sign.md +49 -0
- package/skill-pre/references/onboarding/modules/scripts/app.sh +1485 -0
- package/skill-pre/references/onboarding/modules/scripts/ar_sign_apply.sh +331 -0
- package/skill-pre/references/onboarding/modules/scripts/auth.sh +1040 -0
- package/skill-pre/references/onboarding/modules/scripts/download_key_tool.sh +4 -0
- package/skill-pre/references/onboarding/modules/scripts/error_handler.sh +841 -0
- package/skill-pre/references/onboarding/modules/scripts/mcc.sh +1085 -0
- package/skill-pre/references/onboarding/modules/scripts/network_retry.sh +135 -0
- package/skill-pre/references/onboarding/modules/scripts/query_sign_status.sh +105 -0
- package/skill-pre/references/onboarding/modules/scripts/service.sh +528 -0
- package/skill-pre/references/onboarding/modules/scripts/sign_status_parser.sh +58 -0
- package/skill-pre/references/onboarding/modules/scripts/upload_screenshots.sh +208 -0
- package/skill-pre/references/onboarding/modules/scripts/upload_special_license.sh +195 -0
- package/skill-pre/references/onboarding/modules/service-registration.md +40 -0
- package/skill-pre/references/runtime-entry.md +97 -0
- package/dist/commands/install-current.d.ts +0 -4
- package/dist/commands/install-current.d.ts.map +0 -1
- package/dist/commands/install-current.js.map +0 -1
- package/dist/commands/install.d.ts +0 -10
- package/dist/commands/install.d.ts.map +0 -1
- package/dist/commands/install.js.map +0 -1
- package/dist/commands/prepare-tools.d.ts +0 -5
- package/dist/commands/prepare-tools.d.ts.map +0 -1
- package/dist/commands/prepare-tools.js.map +0 -1
- package/dist/commands/uninstall.d.ts +0 -10
- package/dist/commands/uninstall.d.ts.map +0 -1
- package/dist/commands/uninstall.js.map +0 -1
- package/dist/commands/update.d.ts +0 -10
- package/dist/commands/update.d.ts.map +0 -1
- package/dist/commands/update.js.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/types.d.ts +0 -42
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/utils/alipay-cli.d.ts +0 -20
- package/dist/utils/alipay-cli.d.ts.map +0 -1
- package/dist/utils/alipay-cli.js.map +0 -1
- package/dist/utils/config.d.ts +0 -52
- package/dist/utils/config.d.ts.map +0 -1
- package/dist/utils/config.js.map +0 -1
- package/dist/utils/file.d.ts +0 -77
- package/dist/utils/file.d.ts.map +0 -1
- package/dist/utils/file.js.map +0 -1
- package/dist/utils/jq.d.ts +0 -17
- package/dist/utils/jq.d.ts.map +0 -1
- package/dist/utils/jq.js.map +0 -1
- package/dist/utils/npm.d.ts +0 -17
- package/dist/utils/npm.d.ts.map +0 -1
- package/dist/utils/npm.js.map +0 -1
- package/dist/utils/shell.d.ts +0 -24
- package/dist/utils/shell.d.ts.map +0 -1
- package/dist/utils/shell.js.map +0 -1
package/README.md
CHANGED
|
@@ -3,3 +3,33 @@
|
|
|
3
3
|
支持 AI 按量付费、AI 网页应用收款、AI 移动应用收款的代码开发与产品开通。
|
|
4
4
|
|
|
5
5
|
支付宝 AI 付站点:https://aipay.alipay.com/?from=alipay-aipay-skill
|
|
6
|
+
|
|
7
|
+
## 安装渠道
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# 正式版(默认)
|
|
11
|
+
npx -y @alipay/alipay-aipay@latest install
|
|
12
|
+
|
|
13
|
+
# 预发版
|
|
14
|
+
npx -y @alipay/alipay-aipay@latest install --channel pre
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
两份 Skill 可并存:正式版安装到 Agent 的 `skills/alipay-aipay/`,预发版安装到 `skills/alipay-aipay-pre/`。预发版使用独立名称 `alipay-aipay-pre`,在对话中明确点名或选择预发版使用。`--target` 的 Agent 目标选择规则不变。
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# 只更新或卸载预发版;省略 --channel pre 则只操作正式版
|
|
21
|
+
npx -y @alipay/alipay-aipay@latest update --channel pre
|
|
22
|
+
npx -y @alipay/alipay-aipay@latest uninstall --channel pre
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
安装记录、自更新和卸载按渠道隔离;`--target all` 也只操作所选渠道。两份 Skill 共用系统环境中的 alipay-cli 和 jq,卸载 Skill 不卸载这些工具。
|
|
26
|
+
|
|
27
|
+
## 维护与发布
|
|
28
|
+
|
|
29
|
+
- `skill/` 是正式版源目录,`skill-pre/` 是可独立修改的预发版源目录,构建不会互相覆盖。
|
|
30
|
+
- `package.json.version` 是 npm 分发包版本;`alipayAipayChannels.stable/pre` 分别对应两份 Skill 的 `VERSION`。安装器保留所选 Skill 的版本,不用包版本覆盖。
|
|
31
|
+
- 每次发布提升 npm 包版本;只修改预发内容时,只提升预发 Skill 版本和相应元数据。正式版自更新发现自身版本未变时不下载安装。
|
|
32
|
+
- 两份常规 Skill 自更新器都查询 npm `latest`,只比较自己的渠道版本,并从查询所得精确 npm 包版本中安装对应目录。元数据缺失、非法或为测试版本时保留本地,不切换渠道。
|
|
33
|
+
- 正式版版本从 `1.7.0` 按 `1.7.1`、`1.7.2` 递增;预发版从 `1.7.0-pre` 按 `1.7.1-pre`、`1.7.2-pre` 递增。npm 包版本自此次拆分起独立维护。
|
|
34
|
+
- 旧版 updater 首次升级前仍按 npm 包版本触发一次正式版迁移。正式版 VERSION 可保持 `1.7.0`;旧更新器可能在文件已迁移后返回内部 `VERIFY_FAILED`,启动器会继续读取当前可用入口,不阻塞业务。后续使用新渠道规则。
|
|
35
|
+
- 本次预发版先复制正式版业务能力,后续定制直接修改 `skill-pre/`。对客消息、业务契约和发布校验仍遵循 `AGENTS.md`。
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import fs from 'fs/promises';
|
|
2
|
+
import { getChannelConfig, getSkillVersion, readInstalledChannel, readInstalledVersion, skillVersionKind } from '../utils/channels.js';
|
|
2
3
|
import path from 'path';
|
|
3
4
|
import process from 'process';
|
|
4
|
-
import { getCommandContextForTargetDir,
|
|
5
|
+
import { getCommandContextForTargetDir, PACKAGE_ROOT, } from '../utils/config.js';
|
|
5
6
|
import { installSkillFilesAtPath, readVersionRecord, writeVersionRecordWithFallback, } from '../utils/file.js';
|
|
6
7
|
export const SELF_UPDATE_TARGET_ENV = 'ALIPAY_AIPAY_SELF_UPDATE_TARGET';
|
|
7
8
|
export const SELF_UPDATE_TRANSACTION_ENV = 'ALIPAY_AIPAY_SELF_UPDATE_TRANSACTION';
|
|
@@ -28,28 +29,35 @@ async function requireCurrentSkillRoot(skillDir) {
|
|
|
28
29
|
/**
|
|
29
30
|
* 仅供 Skill 自更新调用:精确覆盖当前目录,不扫描任何 Agent 安装目标。
|
|
30
31
|
*/
|
|
31
|
-
async function installBoundCurrentSkill(target, transactionId) {
|
|
32
|
+
async function installBoundCurrentSkill(target, transactionId, channel) {
|
|
32
33
|
const skillDir = await requireCurrentSkillRoot(target);
|
|
34
|
+
if (readInstalledChannel(skillDir) !== channel)
|
|
35
|
+
throw new Error('自更新渠道与目标不一致');
|
|
36
|
+
if (skillVersionKind(readInstalledVersion(skillDir), channel) === 'beta')
|
|
37
|
+
throw new Error('beta 版本只允许手动 install 换版');
|
|
38
|
+
if (skillVersionKind(getSkillVersion(PACKAGE_ROOT, channel), channel) !== 'release')
|
|
39
|
+
throw new Error('自更新禁止安装 beta');
|
|
40
|
+
const SKILL_NAME = getChannelConfig(channel).skillName;
|
|
33
41
|
const canonicalInstall = path.basename(skillDir) === SKILL_NAME;
|
|
34
42
|
const context = canonicalInstall
|
|
35
|
-
? getCommandContextForTargetDir(path.dirname(skillDir))
|
|
43
|
+
? getCommandContextForTargetDir(path.dirname(skillDir), channel)
|
|
36
44
|
: null;
|
|
37
45
|
const previousRecord = context ? await readVersionRecord(context) : null;
|
|
38
|
-
await installSkillFilesAtPath(PACKAGE_ROOT, skillDir, { transactionId });
|
|
46
|
+
await installSkillFilesAtPath(PACKAGE_ROOT, skillDir, { transactionId, channel });
|
|
39
47
|
if (context && previousRecord) {
|
|
40
48
|
await writeVersionRecordWithFallback(context, {
|
|
41
49
|
...previousRecord,
|
|
42
|
-
version:
|
|
50
|
+
version: getSkillVersion(PACKAGE_ROOT, channel),
|
|
43
51
|
installedAt: new Date().toISOString(),
|
|
44
52
|
});
|
|
45
53
|
}
|
|
46
54
|
}
|
|
47
|
-
export async function installCurrentSkillCommand() {
|
|
55
|
+
export async function installCurrentSkillCommand(channel = 'stable') {
|
|
48
56
|
const target = process.env[SELF_UPDATE_TARGET_ENV] || '';
|
|
49
57
|
const transactionId = process.env[SELF_UPDATE_TRANSACTION_ENV] || '';
|
|
50
58
|
if (!/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/u.test(transactionId)) {
|
|
51
59
|
throw new Error('缺少合法的自更新事务 ID');
|
|
52
60
|
}
|
|
53
|
-
await installBoundCurrentSkill(target, transactionId);
|
|
61
|
+
await installBoundCurrentSkill(target, transactionId, channel);
|
|
54
62
|
}
|
|
55
63
|
//# sourceMappingURL=install-current.js.map
|
package/dist/commands/install.js
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
+
import { getChannelConfig, getSkillVersion } from '../utils/channels.js';
|
|
2
3
|
import ora from 'ora';
|
|
3
4
|
import { spawn } from 'child_process';
|
|
4
5
|
import fs from 'fs';
|
|
5
6
|
import os from 'os';
|
|
6
7
|
import path from 'path';
|
|
7
|
-
import {
|
|
8
|
+
import { getCommandContext, getAllCommandContexts, detectCurrentAgentTarget, DEFAULT_TARGET, PACKAGE_ROOT, TARGET_DIRS, } from '../utils/config.js';
|
|
8
9
|
import { ensureDir, installSkillFiles, readVersionRecord, writeVersionRecordWithFallback, } from '../utils/file.js';
|
|
9
10
|
import { checkAlipayCli } from '../utils/alipay-cli.js';
|
|
10
11
|
import { checkJq, isJqRequiredPlatform, resolveManagedJqAsset } from '../utils/jq.js';
|
|
11
|
-
function resolveInstallPlan(cwd, target) {
|
|
12
|
+
function resolveInstallPlan(cwd, target, channel) {
|
|
12
13
|
if (target !== 'all') {
|
|
13
|
-
const context = getCommandContext(cwd, target);
|
|
14
|
+
const context = getCommandContext(cwd, target, channel);
|
|
14
15
|
return { contexts: [context], primaryTargetDir: path.resolve(context.targetDir) };
|
|
15
16
|
}
|
|
16
17
|
const primaryTarget = detectCurrentAgentTarget() || DEFAULT_TARGET;
|
|
17
|
-
const primaryContext = getCommandContext(cwd, primaryTarget);
|
|
18
|
-
const contexts = getAllCommandContexts(cwd, primaryTarget);
|
|
18
|
+
const primaryContext = getCommandContext(cwd, primaryTarget, channel);
|
|
19
|
+
const contexts = getAllCommandContexts(cwd, primaryTarget, channel);
|
|
19
20
|
const primaryTargetDir = path.resolve(primaryContext.targetDir);
|
|
20
21
|
const ordered = [
|
|
21
22
|
primaryContext,
|
|
@@ -24,19 +25,22 @@ function resolveInstallPlan(cwd, target) {
|
|
|
24
25
|
return { contexts: ordered, primaryTargetDir };
|
|
25
26
|
}
|
|
26
27
|
export async function installCommand(cwd, options = {}) {
|
|
28
|
+
const channel = options.channel ?? 'stable';
|
|
29
|
+
const { skillName: SKILL_NAME, displayName } = getChannelConfig(channel);
|
|
30
|
+
const SKILLS = [{ name: SKILL_NAME, displayName }];
|
|
27
31
|
const target = options.target ?? 'all';
|
|
28
32
|
const skipTools = options.skipTools ?? false;
|
|
29
33
|
const jqRequired = isJqRequiredPlatform();
|
|
30
34
|
const jqPreparationSupported = resolveManagedJqAsset() !== null;
|
|
31
|
-
const installPlan = resolveInstallPlan(cwd, target);
|
|
35
|
+
const installPlan = resolveInstallPlan(cwd, target, channel);
|
|
32
36
|
const { contexts, primaryTargetDir } = installPlan;
|
|
33
|
-
const version =
|
|
37
|
+
const version = getSkillVersion(PACKAGE_ROOT, channel);
|
|
34
38
|
const targetDirLabels = contexts.map((ctx) => ctx.targetDirLabel);
|
|
35
39
|
const targetSkillDirs = contexts.map((ctx) => path.join(ctx.targetDir, SKILL_NAME));
|
|
36
|
-
console.log(chalk.cyan.bold(`\n🚀 @alipay/alipay-aipay v${version}\n`));
|
|
40
|
+
console.log(chalk.cyan.bold(`\n🚀 @alipay/alipay-aipay ${channel} v${version}\n`));
|
|
37
41
|
console.log(chalk.gray('优先安装 Skill 文件;alipay-cli 和用户级 jq 可在后台准备,不调用系统包管理器\n'));
|
|
38
42
|
console.log(chalk.gray(`安装目标: ${targetSkillDirs.join(', ')}`));
|
|
39
|
-
console.log(chalk.gray(`${describeTargetSelection(os.homedir(), target, targetDirLabels, primaryTargetDir)}\n`));
|
|
43
|
+
console.log(chalk.gray(`${describeTargetSelection(os.homedir(), target, targetDirLabels, primaryTargetDir, SKILL_NAME)}\n`));
|
|
40
44
|
// ========== 阶段 1: 环境检查 ==========
|
|
41
45
|
let alipayCliOk = false;
|
|
42
46
|
let jqOk = false;
|
|
@@ -112,12 +116,12 @@ export async function installCommand(cwd, options = {}) {
|
|
|
112
116
|
try {
|
|
113
117
|
const existingRecord = await readVersionRecord(ctx);
|
|
114
118
|
if (existingRecord) {
|
|
115
|
-
console.log(chalk.yellow(`检测到已有安装记录,直接覆盖更新: ${ctx.targetDirLabel}
|
|
119
|
+
console.log(chalk.yellow(`检测到已有安装记录,直接覆盖更新: ${ctx.targetDirLabel}/${SKILL_NAME}/`));
|
|
116
120
|
console.log(` 旧版本: ${existingRecord.version} 安装时间: ${existingRecord.installedAt}`);
|
|
117
121
|
console.log('');
|
|
118
122
|
}
|
|
119
123
|
await ensureDir(ctx.targetDir);
|
|
120
|
-
await installSkillFiles(PACKAGE_ROOT, ctx.targetDir);
|
|
124
|
+
await installSkillFiles(PACKAGE_ROOT, ctx.targetDir, channel);
|
|
121
125
|
const record = {
|
|
122
126
|
version,
|
|
123
127
|
installedAt: new Date().toISOString(),
|
|
@@ -149,7 +153,7 @@ export async function installCommand(cwd, options = {}) {
|
|
|
149
153
|
if (legacyRecordLabels.length > 0) {
|
|
150
154
|
console.log(chalk.yellow('⚠️ 用户配置目录安装记录写入失败,已降级写入 Skill 目录内兼容记录。'));
|
|
151
155
|
for (const targetDirLabel of legacyRecordLabels) {
|
|
152
|
-
console.log(chalk.gray(` 记录位置: ${targetDirLabel}
|
|
156
|
+
console.log(chalk.gray(` 记录位置: ${targetDirLabel}/${SKILL_NAME}/.alipay-aipay-version`));
|
|
153
157
|
}
|
|
154
158
|
console.log('');
|
|
155
159
|
}
|
|
@@ -161,19 +165,19 @@ export async function installCommand(cwd, options = {}) {
|
|
|
161
165
|
process.exit(1);
|
|
162
166
|
}
|
|
163
167
|
}
|
|
164
|
-
function describeTargetSelection(targetRoot, target, targetDirLabels, primaryTargetDir) {
|
|
168
|
+
function describeTargetSelection(targetRoot, target, targetDirLabels, primaryTargetDir, skillName) {
|
|
165
169
|
if (target === 'all') {
|
|
166
170
|
const hasExistingAgentRoot = Object.keys(TARGET_DIRS)
|
|
167
171
|
.map((targetName) => path.dirname(TARGET_DIRS[targetName]))
|
|
168
172
|
.some((rootDir) => fs.existsSync(path.join(targetRoot, rootDir)));
|
|
169
173
|
const primaryLabel = targetDirLabels.find((label) => path.resolve(path.isAbsolute(label) ? label : path.join(targetRoot, label)) === primaryTargetDir) || primaryTargetDir;
|
|
170
174
|
if (!hasExistingAgentRoot && targetDirLabels.length === 1) {
|
|
171
|
-
return `目标选择: --target all;优先安装当前 Agent 目标 ${primaryLabel}
|
|
175
|
+
return `目标选择: --target all;优先安装当前 Agent 目标 ${primaryLabel}/${skillName}/`;
|
|
172
176
|
}
|
|
173
|
-
return `目标选择: --target all;当前 Agent 目标 ${primaryLabel}/
|
|
177
|
+
return `目标选择: --target all;当前 Agent 目标 ${primaryLabel}/${skillName}/ 优先且必须成功,其他已存在目标尽力安装`;
|
|
174
178
|
}
|
|
175
179
|
if (target === 'auto') {
|
|
176
|
-
return `目标选择: --target auto,按当前 Agent/已有安装目录解析为 ${targetDirLabels[0]}
|
|
180
|
+
return `目标选择: --target auto,按当前 Agent/已有安装目录解析为 ${targetDirLabels[0]}/${skillName}/`;
|
|
177
181
|
}
|
|
178
182
|
return `目标选择: --target ${target}`;
|
|
179
183
|
}
|
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
import inquirer from 'inquirer';
|
|
2
|
+
import { getChannelConfig } from '../utils/channels.js';
|
|
2
3
|
import chalk from 'chalk';
|
|
3
4
|
import ora from 'ora';
|
|
4
5
|
import fs from 'fs/promises';
|
|
5
|
-
import {
|
|
6
|
+
import { getCommandContext, getAllCommandContexts } from '../utils/config.js';
|
|
6
7
|
import { removeDir, readVersionRecord, resolveInstalledSkillPaths } from '../utils/file.js';
|
|
7
8
|
export async function uninstallCommand(cwd, options = {}) {
|
|
9
|
+
const channel = options.channel ?? 'stable';
|
|
8
10
|
const target = options.target ?? 'auto';
|
|
9
11
|
if (target === 'all') {
|
|
10
|
-
for (const ctx of getAllCommandContexts(cwd)) {
|
|
12
|
+
for (const ctx of getAllCommandContexts(cwd, undefined, channel)) {
|
|
11
13
|
await uninstallResolvedContext(ctx);
|
|
12
14
|
}
|
|
13
15
|
return;
|
|
14
16
|
}
|
|
15
|
-
const ctx = getCommandContext(cwd, target);
|
|
17
|
+
const ctx = getCommandContext(cwd, target, channel);
|
|
16
18
|
await uninstallResolvedContext(ctx);
|
|
17
19
|
}
|
|
18
20
|
async function uninstallResolvedContext(ctx) {
|
|
21
|
+
const channel = ctx.channel ?? 'stable';
|
|
22
|
+
const { skillName: SKILL_NAME, displayName } = getChannelConfig(channel);
|
|
23
|
+
const SKILLS = [{ name: SKILL_NAME, displayName }];
|
|
19
24
|
// 检查是否有安装记录
|
|
20
25
|
const record = await readVersionRecord(ctx);
|
|
21
26
|
if (!record) {
|
package/dist/commands/update.js
CHANGED
|
@@ -1,52 +1,70 @@
|
|
|
1
1
|
import inquirer from 'inquirer';
|
|
2
|
+
import semver from 'semver';
|
|
3
|
+
import { getChannelConfig, getSkillVersion, readInstalledVersion, skillVersionKind } from '../utils/channels.js';
|
|
2
4
|
import chalk from 'chalk';
|
|
5
|
+
import path from 'path';
|
|
3
6
|
import ora from 'ora';
|
|
4
|
-
import {
|
|
5
|
-
import { ensureDir, installSkillFiles, readVersionRecord, migrateVersionRecord, writeVersionRecordWithFallback, } from '../utils/file.js';
|
|
7
|
+
import { getCommandContext, getAllCommandContexts, PACKAGE_ROOT, } from '../utils/config.js';
|
|
8
|
+
import { ensureDir, installSkillFiles, readVersionRecord, migrateVersionRecord, writeVersionRecordWithFallback, resolveInstalledSkillPaths, } from '../utils/file.js';
|
|
6
9
|
import { checkForUpdates } from '../utils/npm.js';
|
|
7
10
|
import { checkAlipayCli } from '../utils/alipay-cli.js';
|
|
8
11
|
import { checkJq, isJqRequiredPlatform } from '../utils/jq.js';
|
|
9
12
|
export async function updateCommand(cwd, options = {}) {
|
|
13
|
+
const channel = options.channel ?? 'stable';
|
|
10
14
|
const target = options.target ?? 'auto';
|
|
11
15
|
if (target === 'all') {
|
|
12
|
-
for (const ctx of getAllCommandContexts(cwd)) {
|
|
16
|
+
for (const ctx of getAllCommandContexts(cwd, undefined, channel)) {
|
|
13
17
|
await updateResolvedContext(ctx);
|
|
14
18
|
}
|
|
15
19
|
return;
|
|
16
20
|
}
|
|
17
|
-
const ctx = getCommandContext(cwd, target);
|
|
21
|
+
const ctx = getCommandContext(cwd, target, channel);
|
|
18
22
|
await updateResolvedContext(ctx);
|
|
19
23
|
}
|
|
20
24
|
async function updateResolvedContext(ctx) {
|
|
21
|
-
const
|
|
25
|
+
const channel = ctx.channel ?? 'stable';
|
|
26
|
+
const { skillName: SKILL_NAME, displayName } = getChannelConfig(channel);
|
|
27
|
+
const SKILLS = [{ name: SKILL_NAME, displayName }];
|
|
28
|
+
const installCommandText = `npx -y @alipay/alipay-aipay@latest install${channel === 'pre' ? ' --channel pre' : ''}`;
|
|
29
|
+
const currentSkillVersion = getSkillVersion(PACKAGE_ROOT, channel);
|
|
22
30
|
// 检查是否有安装记录
|
|
23
31
|
const record = await readVersionRecord(ctx);
|
|
24
32
|
if (!record) {
|
|
25
33
|
console.log(chalk.yellow('\n未检测到已安装的支付宝 AI 付接入 Skill。'));
|
|
26
|
-
console.log(chalk.gray(`请先运行 \`
|
|
34
|
+
console.log(chalk.gray(`请先运行 \`${installCommandText}\` 安装到 ${ctx.targetDir}/。\n`));
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const installedVersion = readInstalledVersion(path.join(ctx.targetDir, SKILL_NAME)) ?? record.version;
|
|
38
|
+
if ([installedVersion, currentSkillVersion].some(version => skillVersionKind(version, channel) === 'beta')) {
|
|
39
|
+
console.log(chalk.gray('beta 测试版本保持固定;如需换版,请手动运行所选 npm 包的 install 命令。'));
|
|
27
40
|
return;
|
|
28
41
|
}
|
|
29
42
|
console.log(chalk.cyan.bold('\n🔄 检查更新...\n'));
|
|
30
43
|
// 检查 npm 最新版本
|
|
31
44
|
const spinner = ora('正在检查 npm 最新版本...').start();
|
|
32
45
|
try {
|
|
33
|
-
|
|
46
|
+
resolveInstalledSkillPaths(ctx.targetDir, record.skills, [SKILL_NAME]);
|
|
47
|
+
const versionInfo = await checkForUpdates(channel);
|
|
34
48
|
if (versionInfo.needsUpdate) {
|
|
35
|
-
spinner.warn(chalk.yellow('
|
|
49
|
+
spinner.warn(chalk.yellow('当前执行包中的所选渠道版本较旧,未执行更新。\n'));
|
|
36
50
|
console.log(`当前执行版本: ${versionInfo.current}`);
|
|
37
51
|
console.log(`npm latest: ${versionInfo.latest}`);
|
|
38
52
|
console.log(chalk.gray('请运行以下命令安装最新 Skill:'));
|
|
39
|
-
console.log(chalk.cyan(
|
|
53
|
+
console.log(chalk.cyan(` ${installCommandText}\n`));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (semver.valid(record.version) && semver.gt(record.version, currentSkillVersion)) {
|
|
57
|
+
spinner.succeed('本地渠道版本较新,保留当前安装。');
|
|
40
58
|
return;
|
|
41
59
|
}
|
|
42
|
-
if (record.version ===
|
|
60
|
+
if (record.version === currentSkillVersion) {
|
|
43
61
|
await migrateVersionRecord(ctx, record);
|
|
44
62
|
spinner.succeed(chalk.green('Skill 文件已是当前执行包版本!\n'));
|
|
45
|
-
console.log(`当前版本: ${
|
|
63
|
+
console.log(`当前版本: ${currentSkillVersion}`);
|
|
46
64
|
console.log(`安装时间: ${record.installedAt}`);
|
|
47
65
|
}
|
|
48
66
|
else {
|
|
49
|
-
spinner.info(chalk.blue(`发现可安装版本: ${
|
|
67
|
+
spinner.info(chalk.blue(`发现可安装版本: ${currentSkillVersion} (已安装: ${record.version})\n`));
|
|
50
68
|
// 显示更新信息
|
|
51
69
|
console.log('将更新以下 Skill:\n');
|
|
52
70
|
for (const skillName of record.skills) {
|
|
@@ -72,10 +90,10 @@ async function updateResolvedContext(ctx) {
|
|
|
72
90
|
// 开始更新
|
|
73
91
|
const updateSpinner = ora('正在更新 Skill 文件...').start();
|
|
74
92
|
await ensureDir(ctx.targetDir);
|
|
75
|
-
await installSkillFiles(PACKAGE_ROOT, ctx.targetDir);
|
|
76
|
-
//
|
|
93
|
+
await installSkillFiles(PACKAGE_ROOT, ctx.targetDir, channel);
|
|
94
|
+
// 更新版本记录:只记录当前包中所选 Skill 的版本。
|
|
77
95
|
const newRecord = {
|
|
78
|
-
version:
|
|
96
|
+
version: currentSkillVersion,
|
|
79
97
|
installedAt: new Date().toISOString(),
|
|
80
98
|
skills: SKILLS.map((s) => s.name),
|
|
81
99
|
alipayCliInstalled: record.alipayCliInstalled,
|
|
@@ -83,7 +101,7 @@ async function updateResolvedContext(ctx) {
|
|
|
83
101
|
};
|
|
84
102
|
await writeVersionRecordWithFallback(ctx, newRecord);
|
|
85
103
|
updateSpinner.succeed(chalk.green('Skill 文件更新完成!\n'));
|
|
86
|
-
console.log(`版本: ${record.version} → ${
|
|
104
|
+
console.log(`版本: ${record.version} → ${currentSkillVersion}`);
|
|
87
105
|
}
|
|
88
106
|
console.log('');
|
|
89
107
|
// 重新检查环境工具
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
+
import { parseChannel } from './utils/channels.js';
|
|
2
3
|
import chalk from 'chalk';
|
|
3
4
|
import { getPackageVersion } from './utils/config.js';
|
|
4
5
|
import { installCommand } from './commands/install.js';
|
|
@@ -22,6 +23,7 @@ program
|
|
|
22
23
|
// install 命令
|
|
23
24
|
program
|
|
24
25
|
.command('install')
|
|
26
|
+
.option('--channel <channel>', 'Skill 渠道: stable | pre', parseChannel, 'stable')
|
|
25
27
|
.description('安装支付宝 AI 付接入 Skill(Skill 文件优先完成,工具准备不阻塞安装)')
|
|
26
28
|
.option('--target <target>', '安装目标: all | agents | codex | claude | auto', 'all')
|
|
27
29
|
.option('--with-jq', '兼容参数;macOS/Linux 缺少 jq 时默认已在 detached 后台准备')
|
|
@@ -29,24 +31,27 @@ program
|
|
|
29
31
|
.action(async (options) => {
|
|
30
32
|
await installCommand(process.cwd(), {
|
|
31
33
|
target: parseTarget(options.target),
|
|
34
|
+
channel: options.channel,
|
|
32
35
|
skipTools: Boolean(options.skipTools),
|
|
33
36
|
});
|
|
34
37
|
});
|
|
35
38
|
// uninstall 命令
|
|
36
39
|
program
|
|
37
40
|
.command('uninstall')
|
|
41
|
+
.option('--channel <channel>', 'Skill 渠道: stable | pre', parseChannel, 'stable')
|
|
38
42
|
.description('卸载已安装的支付宝 AI 付接入 Skill')
|
|
39
43
|
.option('--target <target>', '卸载目标: all | agents | codex | claude | auto', 'auto')
|
|
40
44
|
.action(async (options) => {
|
|
41
|
-
await uninstallCommand(process.cwd(), { target: parseTarget(options.target) });
|
|
45
|
+
await uninstallCommand(process.cwd(), { target: parseTarget(options.target), channel: options.channel });
|
|
42
46
|
});
|
|
43
47
|
// update 命令
|
|
44
48
|
program
|
|
45
49
|
.command('update')
|
|
50
|
+
.option('--channel <channel>', 'Skill 渠道: stable | pre', parseChannel, 'stable')
|
|
46
51
|
.description('检查并更新支付宝 AI 付接入 Skill')
|
|
47
52
|
.option('--target <target>', '更新目标: all | agents | codex | claude | auto', 'auto')
|
|
48
53
|
.action(async (options) => {
|
|
49
|
-
await updateCommand(process.cwd(), { target: parseTarget(options.target) });
|
|
54
|
+
await updateCommand(process.cwd(), { target: parseTarget(options.target), channel: options.channel });
|
|
50
55
|
});
|
|
51
56
|
program
|
|
52
57
|
.command('prepare-tools', { hidden: true })
|
|
@@ -57,9 +62,10 @@ program
|
|
|
57
62
|
});
|
|
58
63
|
program
|
|
59
64
|
.command('install-current', { hidden: true })
|
|
65
|
+
.option('--channel <channel>', 'Skill 渠道', parseChannel, 'stable')
|
|
60
66
|
.description('精确覆盖当前运行中的 Skill 目录')
|
|
61
|
-
.action(async () => {
|
|
62
|
-
await installCurrentSkillCommand();
|
|
67
|
+
.action(async (options) => {
|
|
68
|
+
await installCurrentSkillCommand(options.channel);
|
|
63
69
|
});
|
|
64
70
|
// 默认行为:无参数时直接执行安装流程
|
|
65
71
|
if (process.argv.length === 2) {
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import semver from 'semver';
|
|
4
|
+
export const CHANNEL_FILE = 'references/normal/json/release-channel.json';
|
|
5
|
+
export function parseChannel(value) {
|
|
6
|
+
if (value === 'stable' || value === 'pre')
|
|
7
|
+
return value;
|
|
8
|
+
throw new Error('无效的 --channel;可选值: stable | pre');
|
|
9
|
+
}
|
|
10
|
+
export function getChannelConfig(channel = 'stable') {
|
|
11
|
+
parseChannel(channel);
|
|
12
|
+
return channel === 'pre'
|
|
13
|
+
? { channel, skillName: 'alipay-aipay-pre', sourceDir: 'skill-pre', displayName: '支付宝 AI 付接入 Skill 预发版' }
|
|
14
|
+
: { channel, skillName: 'alipay-aipay', sourceDir: 'skill', displayName: '支付宝 AI 付接入 Skill' };
|
|
15
|
+
}
|
|
16
|
+
export function readInstalledChannel(skillDir) {
|
|
17
|
+
const source = fs.readFileSync(path.join(skillDir, 'SKILL.md'), 'utf8');
|
|
18
|
+
const declaredName = source.match(/^name:\s*(\S+)\s*$/m)?.[1];
|
|
19
|
+
const identity = declaredName === 'alipay-aipay-pre' ? 'pre' : 'stable';
|
|
20
|
+
try {
|
|
21
|
+
const file = path.join(skillDir, CHANNEL_FILE);
|
|
22
|
+
if (!fs.lstatSync(file).isFile())
|
|
23
|
+
throw new Error('渠道文件必须是普通文件');
|
|
24
|
+
const channel = parseChannel(JSON.parse(fs.readFileSync(file, 'utf8')).channel);
|
|
25
|
+
if (channel !== identity)
|
|
26
|
+
throw new Error('Skill 名称与渠道不一致');
|
|
27
|
+
return channel;
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
if (error.code === 'ENOENT' && identity === 'stable')
|
|
31
|
+
return 'stable';
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export function skillVersionKind(version, channel) {
|
|
36
|
+
if (typeof version !== 'string')
|
|
37
|
+
return null;
|
|
38
|
+
const parsed = semver.parse(version);
|
|
39
|
+
if (!parsed)
|
|
40
|
+
return null;
|
|
41
|
+
const suffix = parsed.prerelease.join('.');
|
|
42
|
+
if (suffix === (channel === 'pre' ? 'pre' : ''))
|
|
43
|
+
return 'release';
|
|
44
|
+
const pattern = channel === 'pre' ? /^pre-beta(?:\d+|\.\d+)?$/u : /^beta(?:\d+|\.\d+)?$/u;
|
|
45
|
+
return pattern.test(suffix) ? 'beta' : null;
|
|
46
|
+
}
|
|
47
|
+
export function readInstalledVersion(skillDir) {
|
|
48
|
+
try {
|
|
49
|
+
const file = path.join(skillDir, 'VERSION');
|
|
50
|
+
if (!fs.lstatSync(file).isFile())
|
|
51
|
+
return null;
|
|
52
|
+
return fs.readFileSync(file, 'utf8').trim();
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export function getSkillVersion(packageRoot, channel = 'stable') {
|
|
59
|
+
const config = getChannelConfig(channel);
|
|
60
|
+
const version = fs.readFileSync(path.join(packageRoot, config.sourceDir, 'VERSION'), 'utf8').trim();
|
|
61
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf8'));
|
|
62
|
+
if (!semver.valid(version) || !skillVersionKind(version, channel) || pkg.alipayAipayChannels?.[channel] !== version) {
|
|
63
|
+
throw new Error(`渠道 ${channel} 的 VERSION 与 npm 元数据不一致或非法`);
|
|
64
|
+
}
|
|
65
|
+
return version;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=channels.js.map
|
package/dist/utils/config.js
CHANGED
|
@@ -4,6 +4,7 @@ import { createHash } from 'crypto';
|
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
5
|
import fs from 'fs';
|
|
6
6
|
import { execFileSync } from 'child_process';
|
|
7
|
+
import { getChannelConfig } from './channels.js';
|
|
7
8
|
// 获取当前包的根目录
|
|
8
9
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
10
|
export const PACKAGE_ROOT = path.resolve(__dirname, '../../');
|
|
@@ -99,7 +100,8 @@ export function detectCurrentAgentTarget() {
|
|
|
99
100
|
/**
|
|
100
101
|
* 解析安装目标
|
|
101
102
|
*/
|
|
102
|
-
export function resolveInstallTarget(cwd, target = 'auto') {
|
|
103
|
+
export function resolveInstallTarget(cwd, target = 'auto', channel = 'stable') {
|
|
104
|
+
const SKILL_NAME = getChannelConfig(channel).skillName;
|
|
103
105
|
if (target === 'agents' || target === 'claude') {
|
|
104
106
|
return target;
|
|
105
107
|
}
|
|
@@ -153,15 +155,17 @@ export function getExtraSkillDirs() {
|
|
|
153
155
|
.map((item) => item.trim())
|
|
154
156
|
.filter((item) => item.length > 0 && !item.includes('\0'));
|
|
155
157
|
}
|
|
156
|
-
function createCommandContext(cwd, targetDirLabel) {
|
|
158
|
+
function createCommandContext(cwd, targetDirLabel, channel = 'stable') {
|
|
159
|
+
const SKILL_NAME = getChannelConfig(channel).skillName;
|
|
157
160
|
const targetDir = path.isAbsolute(targetDirLabel)
|
|
158
161
|
? targetDirLabel
|
|
159
162
|
: path.join(cwd, targetDirLabel);
|
|
160
163
|
const skillDir = path.join(targetDir, SKILL_NAME);
|
|
161
164
|
const resolvedTargetDir = path.resolve(targetDir);
|
|
162
|
-
const versionFileName = `${createHash('sha256').update(resolvedTargetDir).digest('hex')}.json`;
|
|
165
|
+
const versionFileName = `${createHash('sha256').update(channel === 'stable' ? resolvedTargetDir : `${resolvedTargetDir}\0${channel}`).digest('hex')}.json`;
|
|
163
166
|
return {
|
|
164
167
|
cwd,
|
|
168
|
+
channel,
|
|
165
169
|
targetDir,
|
|
166
170
|
versionFile: path.join(os.homedir(), '.config', 'alipay-aipay', 'install-records', versionFileName),
|
|
167
171
|
legacyVersionFile: path.join(skillDir, VERSION_FILE),
|
|
@@ -171,12 +175,12 @@ function createCommandContext(cwd, targetDirLabel) {
|
|
|
171
175
|
/**
|
|
172
176
|
* 为已经解析出的 skills 父目录构造命令上下文。
|
|
173
177
|
*/
|
|
174
|
-
export function getCommandContextForTargetDir(targetDir) {
|
|
178
|
+
export function getCommandContextForTargetDir(targetDir, channel = 'stable') {
|
|
175
179
|
if (!path.isAbsolute(targetDir) || targetDir.includes('\0')) {
|
|
176
180
|
throw new Error('Skill 目标父目录必须是绝对路径');
|
|
177
181
|
}
|
|
178
182
|
const resolvedTargetDir = path.resolve(targetDir);
|
|
179
|
-
return createCommandContext(resolvedTargetDir, resolvedTargetDir);
|
|
183
|
+
return createCommandContext(resolvedTargetDir, resolvedTargetDir, channel);
|
|
180
184
|
}
|
|
181
185
|
function getExistingInstallTargetNames(cwd) {
|
|
182
186
|
return getAllInstallTargetNames().filter((targetName) => fs.existsSync(path.join(cwd, TARGET_ROOT_DIRS[targetName])));
|
|
@@ -185,17 +189,17 @@ function getExistingInstallTargetNames(cwd) {
|
|
|
185
189
|
* 获取批量安装目标上下文。普通命令扫描用户 Home 下已有的内置 Agent 目录;
|
|
186
190
|
* 若没有任何已存在目录,则使用调用方指定的回退目标。环境变量可追加兼容 Skill 目录。
|
|
187
191
|
*/
|
|
188
|
-
export function getAllCommandContexts(cwd, fallbackTarget = DEFAULT_TARGET) {
|
|
192
|
+
export function getAllCommandContexts(cwd, fallbackTarget = DEFAULT_TARGET, channel = 'stable') {
|
|
189
193
|
const extraSkillDirs = getExtraSkillDirs();
|
|
190
194
|
const homeDir = os.homedir();
|
|
191
195
|
const targetNames = getExistingInstallTargetNames(homeDir);
|
|
192
196
|
if (targetNames.length === 0) {
|
|
193
197
|
targetNames.push(fallbackTarget);
|
|
194
198
|
}
|
|
195
|
-
const contexts = targetNames.map((targetName) => createCommandContext(homeDir, TARGET_DIRS[targetName]));
|
|
199
|
+
const contexts = targetNames.map((targetName) => createCommandContext(homeDir, TARGET_DIRS[targetName], channel));
|
|
196
200
|
const seen = new Set(contexts.map((ctx) => path.resolve(ctx.targetDir)));
|
|
197
201
|
for (const extraDir of extraSkillDirs) {
|
|
198
|
-
const ctx = createCommandContext(cwd, extraDir);
|
|
202
|
+
const ctx = createCommandContext(cwd, extraDir, channel);
|
|
199
203
|
const resolved = path.resolve(ctx.targetDir);
|
|
200
204
|
if (seen.has(resolved))
|
|
201
205
|
continue;
|
|
@@ -207,11 +211,11 @@ export function getAllCommandContexts(cwd, fallbackTarget = DEFAULT_TARGET) {
|
|
|
207
211
|
/**
|
|
208
212
|
* 获取命令上下文
|
|
209
213
|
*/
|
|
210
|
-
export function getCommandContext(_cwd, target = 'auto') {
|
|
214
|
+
export function getCommandContext(_cwd, target = 'auto', channel = 'stable') {
|
|
211
215
|
const homeDir = os.homedir();
|
|
212
|
-
const targetName = resolveInstallTarget(homeDir, target);
|
|
216
|
+
const targetName = resolveInstallTarget(homeDir, target, channel);
|
|
213
217
|
const targetDirLabel = TARGET_DIRS[targetName];
|
|
214
|
-
return createCommandContext(homeDir, targetDirLabel);
|
|
218
|
+
return createCommandContext(homeDir, targetDirLabel, channel);
|
|
215
219
|
}
|
|
216
220
|
/**
|
|
217
221
|
* 获取包版本
|
package/dist/utils/file.js
CHANGED
|
@@ -2,7 +2,7 @@ import fs from 'fs/promises';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { randomUUID } from 'crypto';
|
|
4
4
|
import { setTimeout as delay } from 'timers/promises';
|
|
5
|
-
import {
|
|
5
|
+
import { getChannelConfig, getSkillVersion, readInstalledChannel } from './channels.js';
|
|
6
6
|
/**
|
|
7
7
|
* 检查目录是否存在
|
|
8
8
|
*/
|
|
@@ -236,8 +236,8 @@ export async function writeVersionRecordWithFallback(ctx, record) {
|
|
|
236
236
|
* 安装 Skill 文件到目标目录
|
|
237
237
|
* 从包内 skill/ 目录复制 SKILL.md + references/ 到目标 skills 目录
|
|
238
238
|
*/
|
|
239
|
-
export async function installSkillFiles(packageRoot, targetDir) {
|
|
240
|
-
return installSkillFilesAtPath(packageRoot, path.join(targetDir,
|
|
239
|
+
export async function installSkillFiles(packageRoot, targetDir, channel = 'stable') {
|
|
240
|
+
return installSkillFilesAtPath(packageRoot, path.join(targetDir, getChannelConfig(channel).skillName), { channel });
|
|
241
241
|
}
|
|
242
242
|
/**
|
|
243
243
|
* 原子安装到已经确定的单个 Skill 目录。自更新使用事务 ID,便于超时恢复。
|
|
@@ -246,6 +246,8 @@ export async function installSkillFilesAtPath(packageRoot, skillTargetDir, optio
|
|
|
246
246
|
if (!path.isAbsolute(skillTargetDir) || skillTargetDir.includes('\0')) {
|
|
247
247
|
throw new Error('Skill 安装目录必须是绝对路径');
|
|
248
248
|
}
|
|
249
|
+
const channel = options.channel ?? 'stable';
|
|
250
|
+
const { skillName: SKILL_NAME, sourceDir: SKILL_DIR } = getChannelConfig(channel);
|
|
249
251
|
const transactionId = options.transactionId;
|
|
250
252
|
if (transactionId && !/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/u.test(transactionId)) {
|
|
251
253
|
throw new Error('无效的 Skill 安装事务 ID');
|
|
@@ -253,7 +255,20 @@ export async function installSkillFilesAtPath(packageRoot, skillTargetDir, optio
|
|
|
253
255
|
const resolvedSkillTargetDir = path.resolve(skillTargetDir);
|
|
254
256
|
const targetDir = path.dirname(resolvedSkillTargetDir);
|
|
255
257
|
const skillSourceDir = path.join(packageRoot, SKILL_DIR);
|
|
256
|
-
const
|
|
258
|
+
const skillVersion = getSkillVersion(packageRoot, channel);
|
|
259
|
+
if (readInstalledChannel(skillSourceDir) !== channel)
|
|
260
|
+
throw new Error('安装源渠道不匹配');
|
|
261
|
+
for (const file of ['SKILL.md', 'VERSION', 'references/runtime-entry.md']) {
|
|
262
|
+
if (!(await fs.lstat(path.join(skillSourceDir, file))).isFile())
|
|
263
|
+
throw new Error('Skill 安装源不完整');
|
|
264
|
+
}
|
|
265
|
+
const oppositeName = getChannelConfig(channel === 'stable' ? 'pre' : 'stable').skillName;
|
|
266
|
+
if (path.basename(resolvedSkillTargetDir) === oppositeName)
|
|
267
|
+
throw new Error('禁止覆盖另一渠道目录');
|
|
268
|
+
if (await pathExists(path.join(resolvedSkillTargetDir, 'SKILL.md'))) {
|
|
269
|
+
if (readInstalledChannel(resolvedSkillTargetDir) !== channel)
|
|
270
|
+
throw new Error('禁止跨渠道覆盖 Skill');
|
|
271
|
+
}
|
|
257
272
|
await ensureDir(targetDir);
|
|
258
273
|
const stagingDir = transactionId
|
|
259
274
|
? path.join(targetDir, `.${SKILL_NAME}-install-${transactionId}`)
|
|
@@ -266,9 +281,7 @@ export async function installSkillFilesAtPath(packageRoot, skillTargetDir, optio
|
|
|
266
281
|
try {
|
|
267
282
|
await fs.copyFile(path.join(skillSourceDir, 'SKILL.md'), path.join(stagingDir, 'SKILL.md'));
|
|
268
283
|
await copyDirWithPerms(path.join(skillSourceDir, 'references'), path.join(stagingDir, 'references'));
|
|
269
|
-
|
|
270
|
-
await fs.writeFile(path.join(stagingDir, 'VERSION'), `${packageJson.version}\n`, 'utf-8');
|
|
271
|
-
}
|
|
284
|
+
await fs.copyFile(path.join(skillSourceDir, 'VERSION'), path.join(stagingDir, 'VERSION'));
|
|
272
285
|
if (await pathExists(resolvedSkillTargetDir)) {
|
|
273
286
|
try {
|
|
274
287
|
await fs.rename(resolvedSkillTargetDir, backupDir);
|
|
@@ -286,8 +299,8 @@ export async function installSkillFilesAtPath(packageRoot, skillTargetDir, optio
|
|
|
286
299
|
catch (installError) {
|
|
287
300
|
const installErrorCode = installError.code;
|
|
288
301
|
const sameVersionInstalled = ['EEXIST', 'ENOTEMPTY', 'ENOENT'].includes(installErrorCode ?? '')
|
|
289
|
-
? await waitForCompleteInstalledVersion(resolvedSkillTargetDir,
|
|
290
|
-
: await hasCompleteInstalledVersion(resolvedSkillTargetDir,
|
|
302
|
+
? await waitForCompleteInstalledVersion(resolvedSkillTargetDir, skillVersion)
|
|
303
|
+
: await hasCompleteInstalledVersion(resolvedSkillTargetDir, skillVersion);
|
|
291
304
|
if (sameVersionInstalled) {
|
|
292
305
|
if (previousInstallMoved) {
|
|
293
306
|
await removeDir(backupDir);
|
|
@@ -303,7 +316,7 @@ export async function installSkillFilesAtPath(packageRoot, skillTargetDir, optio
|
|
|
303
316
|
catch (restoreError) {
|
|
304
317
|
const restoreErrorCode = restoreError.code;
|
|
305
318
|
if (['EEXIST', 'ENOTEMPTY', 'ENOENT'].includes(restoreErrorCode ?? '') &&
|
|
306
|
-
await waitForCompleteInstalledVersion(resolvedSkillTargetDir,
|
|
319
|
+
await waitForCompleteInstalledVersion(resolvedSkillTargetDir, skillVersion)) {
|
|
307
320
|
await removeDir(backupDir);
|
|
308
321
|
previousInstallMoved = false;
|
|
309
322
|
return;
|