@alipay/alipay-aipay 1.7.0 → 1.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/README.md +30 -0
  2. package/dist/commands/install-current.js +15 -7
  3. package/dist/commands/install.js +20 -16
  4. package/dist/commands/uninstall.js +8 -3
  5. package/dist/commands/update.js +34 -16
  6. package/dist/index.js +10 -4
  7. package/dist/utils/channels.js +67 -0
  8. package/dist/utils/config.js +15 -11
  9. package/dist/utils/file.js +23 -10
  10. package/dist/utils/npm.js +19 -33
  11. package/package.json +8 -3
  12. package/skill/SKILL.md +2 -0
  13. package/skill/references/normal/json/release-channel.json +1 -0
  14. package/skill/references/normal/scripts/self_update.mjs +62 -17
  15. package/skill/references/normal/self-update.md +3 -1
  16. package/skill-pre/SKILL.md +65 -0
  17. package/skill-pre/VERSION +1 -0
  18. package/skill-pre/references/integration/flow.md +602 -0
  19. package/skill-pre/references/integration/modules/alipay-sdk-reminder.md +281 -0
  20. package/skill-pre/references/integration/modules/checklist.md +154 -0
  21. 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
  22. 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
  23. 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
  24. 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
  25. 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
  26. 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
  27. 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
  28. 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
  29. 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
  30. 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
  31. 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
  32. 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
  33. 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
  34. 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
  35. 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
  36. 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
  37. 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
  38. 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
  39. 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
  40. 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
  41. 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
  42. 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
  43. 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
  44. 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
  45. 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
  46. 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
  47. 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
  48. 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
  49. 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
  50. 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
  51. 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
  52. 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
  53. 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
  54. 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
  55. 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
  56. 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
  57. 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
  58. 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
  59. 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
  60. 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
  61. package/skill-pre/references/integration/modules/interface-contract/aipay-interface-contract.md +52 -0
  62. package/skill-pre/references/integration/modules/interface-contract/apppay-interface-contract.md +45 -0
  63. package/skill-pre/references/integration/modules/interface-contract/common-trade-contract.md +42 -0
  64. package/skill-pre/references/integration/modules/interface-contract/notify-url-contract.md +68 -0
  65. package/skill-pre/references/integration/modules/interface-contract/webpay-interface-contract.md +44 -0
  66. package/skill-pre/references/integration/modules/interface-guide.md +61 -0
  67. package/skill-pre/references/integration/modules/product-decision.md +73 -0
  68. package/skill-pre/references/integration/modules/sandbox/a2m-sandbox-test.md +235 -0
  69. package/skill-pre/references/integration/modules/sandbox/alipay-sandbox-tool.md +142 -0
  70. package/skill-pre/references/integration/modules/sandbox/sandbox-setup-guide.md +239 -0
  71. package/skill-pre/references/integration/modules/scripts/local_402_sandbox_pay.py +900 -0
  72. package/skill-pre/references/integration/modules/scripts/sandbox_config.sh +347 -0
  73. package/skill-pre/references/integration/modules/troubleshooting-flow.md +28 -0
  74. package/skill-pre/references/normal/alipay-cli-env.md +169 -0
  75. package/skill-pre/references/normal/conversation-telemetry.md +101 -0
  76. package/skill-pre/references/normal/full-process-routing.md +92 -0
  77. package/skill-pre/references/normal/integration-worker.md +90 -0
  78. package/skill-pre/references/normal/json/customer-messages.json +1 -0
  79. package/skill-pre/references/normal/json/managed-jq-assets.json +1 -0
  80. package/skill-pre/references/normal/json/policy-rules.json +1 -0
  81. package/skill-pre/references/normal/json/release-channel.json +1 -0
  82. package/skill-pre/references/normal/rejection-guide.md +41 -0
  83. package/skill-pre/references/normal/scripts/agent_platform.mjs +43 -0
  84. package/skill-pre/references/normal/scripts/alipay_cli_env.mjs +34 -0
  85. package/skill-pre/references/normal/scripts/alipay_cli_env.sh +55 -0
  86. package/skill-pre/references/normal/scripts/alipay_cli_refresh.mjs +129 -0
  87. package/skill-pre/references/normal/scripts/auth_runtime_runner.mjs +60 -0
  88. package/skill-pre/references/normal/scripts/checklist_sections.mjs +43 -0
  89. package/skill-pre/references/normal/scripts/common.sh +365 -0
  90. package/skill-pre/references/normal/scripts/conversation_telemetry.mjs +105 -0
  91. package/skill-pre/references/normal/scripts/detect_dev_tool.sh +79 -0
  92. package/skill-pre/references/normal/scripts/flow_loader.mjs +237 -0
  93. package/skill-pre/references/normal/scripts/integration_context_runner.mjs +151 -0
  94. package/skill-pre/references/normal/scripts/integration_message_runner.mjs +1456 -0
  95. package/skill-pre/references/normal/scripts/interaction_reply.mjs +140 -0
  96. package/skill-pre/references/normal/scripts/managed_jq.mjs +215 -0
  97. package/skill-pre/references/normal/scripts/onboarding_discovery_runner.mjs +387 -0
  98. package/skill-pre/references/normal/scripts/onboarding_message_runner.mjs +1425 -0
  99. package/skill-pre/references/normal/scripts/onboarding_recovery_runner.mjs +100 -0
  100. package/skill-pre/references/normal/scripts/open_official_url.sh +205 -0
  101. package/skill-pre/references/normal/scripts/platform_compat.mjs +42 -0
  102. package/skill-pre/references/normal/scripts/preview_runtime.mjs +151 -0
  103. package/skill-pre/references/normal/scripts/project_route_inspector.sh +132 -0
  104. package/skill-pre/references/normal/scripts/python_script_runner.mjs +58 -0
  105. package/skill-pre/references/normal/scripts/render_customer_message.mjs +1792 -0
  106. package/skill-pre/references/normal/scripts/runtime.mjs +271 -0
  107. package/skill-pre/references/normal/scripts/self_update.mjs +376 -0
  108. package/skill-pre/references/normal/scripts/telemetry.mjs +2102 -0
  109. package/skill-pre/references/normal/self-update.md +7 -0
  110. package/skill-pre/references/normal/telemetry.md +70 -0
  111. package/skill-pre/references/onboarding/assets/keygen.html +927 -0
  112. package/skill-pre/references/onboarding/flow.md +607 -0
  113. package/skill-pre/references/onboarding/modules/app-release.md +90 -0
  114. package/skill-pre/references/onboarding/modules/authorization.md +43 -0
  115. package/skill-pre/references/onboarding/modules/error-handling.md +62 -0
  116. package/skill-pre/references/onboarding/modules/product-sign.md +49 -0
  117. package/skill-pre/references/onboarding/modules/scripts/app.sh +1485 -0
  118. package/skill-pre/references/onboarding/modules/scripts/ar_sign_apply.sh +331 -0
  119. package/skill-pre/references/onboarding/modules/scripts/auth.sh +1040 -0
  120. package/skill-pre/references/onboarding/modules/scripts/download_key_tool.sh +4 -0
  121. package/skill-pre/references/onboarding/modules/scripts/error_handler.sh +841 -0
  122. package/skill-pre/references/onboarding/modules/scripts/mcc.sh +1085 -0
  123. package/skill-pre/references/onboarding/modules/scripts/network_retry.sh +135 -0
  124. package/skill-pre/references/onboarding/modules/scripts/query_sign_status.sh +105 -0
  125. package/skill-pre/references/onboarding/modules/scripts/service.sh +528 -0
  126. package/skill-pre/references/onboarding/modules/scripts/sign_status_parser.sh +58 -0
  127. package/skill-pre/references/onboarding/modules/scripts/upload_screenshots.sh +208 -0
  128. package/skill-pre/references/onboarding/modules/scripts/upload_special_license.sh +195 -0
  129. package/skill-pre/references/onboarding/modules/service-registration.md +40 -0
  130. package/skill-pre/references/runtime-entry.md +99 -0
  131. package/dist/commands/install-current.d.ts +0 -4
  132. package/dist/commands/install-current.d.ts.map +0 -1
  133. package/dist/commands/install-current.js.map +0 -1
  134. package/dist/commands/install.d.ts +0 -10
  135. package/dist/commands/install.d.ts.map +0 -1
  136. package/dist/commands/install.js.map +0 -1
  137. package/dist/commands/prepare-tools.d.ts +0 -5
  138. package/dist/commands/prepare-tools.d.ts.map +0 -1
  139. package/dist/commands/prepare-tools.js.map +0 -1
  140. package/dist/commands/uninstall.d.ts +0 -10
  141. package/dist/commands/uninstall.d.ts.map +0 -1
  142. package/dist/commands/uninstall.js.map +0 -1
  143. package/dist/commands/update.d.ts +0 -10
  144. package/dist/commands/update.d.ts.map +0 -1
  145. package/dist/commands/update.js.map +0 -1
  146. package/dist/index.d.ts +0 -2
  147. package/dist/index.d.ts.map +0 -1
  148. package/dist/index.js.map +0 -1
  149. package/dist/types.d.ts +0 -42
  150. package/dist/types.d.ts.map +0 -1
  151. package/dist/types.js.map +0 -1
  152. package/dist/utils/alipay-cli.d.ts +0 -20
  153. package/dist/utils/alipay-cli.d.ts.map +0 -1
  154. package/dist/utils/alipay-cli.js.map +0 -1
  155. package/dist/utils/config.d.ts +0 -52
  156. package/dist/utils/config.d.ts.map +0 -1
  157. package/dist/utils/config.js.map +0 -1
  158. package/dist/utils/file.d.ts +0 -77
  159. package/dist/utils/file.d.ts.map +0 -1
  160. package/dist/utils/file.js.map +0 -1
  161. package/dist/utils/jq.d.ts +0 -17
  162. package/dist/utils/jq.d.ts.map +0 -1
  163. package/dist/utils/jq.js.map +0 -1
  164. package/dist/utils/npm.d.ts +0 -17
  165. package/dist/utils/npm.d.ts.map +0 -1
  166. package/dist/utils/npm.js.map +0 -1
  167. package/dist/utils/shell.d.ts +0 -24
  168. package/dist/utils/shell.d.ts.map +0 -1
  169. package/dist/utils/shell.js.map +0 -1
@@ -0,0 +1,271 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { spawnSync } from 'node:child_process';
4
+ import path from 'node:path';
5
+ import process from 'node:process';
6
+ import { fileURLToPath } from 'node:url';
7
+
8
+ import { applyTelemetrySession, currentRunContext, startTelemetryRun } from './telemetry.mjs';
9
+ import { applyAgentPlatform } from './agent_platform.mjs';
10
+
11
+ const scriptDir = path.dirname(fileURLToPath(import.meta.url));
12
+ const referencesDir = path.resolve(scriptDir, '../..');
13
+ const flowDirs = Object.freeze({
14
+ integration: path.join(referencesDir, 'integration'),
15
+ onboarding: path.join(referencesDir, 'onboarding')
16
+ });
17
+
18
+ const shellEntrypoints = Object.freeze({
19
+ sandbox: ['integration', 'sandbox_config.sh'],
20
+ mcc: ['onboarding', 'mcc.sh'],
21
+ auth: ['onboarding', 'auth.sh'],
22
+ screenshots: ['onboarding', 'upload_screenshots.sh'],
23
+ 'special-license': ['onboarding', 'upload_special_license.sh'],
24
+ sign: ['onboarding', 'ar_sign_apply.sh'],
25
+ service: ['onboarding', 'service.sh'],
26
+ app: ['onboarding', 'app.sh']
27
+ });
28
+
29
+ const nodeEntrypoints = Object.freeze({
30
+ preview: ['preview_runtime.mjs', 'runPreviewCli'],
31
+ 'key-tool': ['preview_runtime.mjs', 'runManualKeyToolCli'],
32
+ telemetry: ['telemetry.mjs', 'runTelemetryCli'],
33
+ flow: ['flow_loader.mjs', 'runFlowCli'],
34
+ 'onboarding-message': ['onboarding_message_runner.mjs', 'runOnboardingMessageCli'],
35
+ 'integration-message': ['integration_message_runner.mjs', 'runIntegrationMessageCli'],
36
+ render: ['render_customer_message.mjs', 'runRenderCustomerMessageCli'],
37
+ reply: ['interaction_reply.mjs', 'runInteractionReplyCli'],
38
+ 'integration-context': ['integration_context_runner.mjs', 'runIntegrationContextCli'],
39
+ 'onboarding-discovery': ['onboarding_discovery_runner.mjs', 'runOnboardingDiscoveryCli'],
40
+ 'onboarding-recovery': ['onboarding_recovery_runner.mjs', 'runOnboardingRecoveryCli']
41
+ });
42
+
43
+ export const runtimeDomains = Object.freeze([
44
+ 'self-update',
45
+ 'integration-bootstrap',
46
+ 'onboarding-bootstrap',
47
+ 'onboarding-execute-ready',
48
+ ...Object.keys(nodeEntrypoints),
49
+ 'env',
50
+ ...Object.keys(shellEntrypoints),
51
+ 'a2m'
52
+ ]);
53
+
54
+ function cliArgv(args) {
55
+ return [process.execPath, fileURLToPath(import.meta.url), ...args];
56
+ }
57
+
58
+ function runShell(script, cwd, args) {
59
+ const result = spawnSync('bash', [script, ...args], {
60
+ cwd,
61
+ env: process.env,
62
+ stdio: 'inherit',
63
+ shell: false
64
+ });
65
+ if (result.error) throw result.error;
66
+ process.exitCode = Number.isInteger(result.status) ? result.status : 1;
67
+ }
68
+
69
+ function shellPath(domain) {
70
+ const [flow, basename] = shellEntrypoints[domain];
71
+ const cwd = flowDirs[flow];
72
+ return [path.join(cwd, 'modules/scripts', basename), cwd];
73
+ }
74
+
75
+ function runtimeError(domain, error) {
76
+ const message = String(error?.message || error).replace(/[\r\n]/gu, ' ');
77
+ if (domain === 'self-update') return process.stderr.write('SELF_UPDATE:CHECK_FAILED\n');
78
+ if (domain === 'render') {
79
+ process.stderr.write('当前步骤的标准消息无法安全生成,已停止后续动作。请按 MESSAGE_RENDER_ERROR 的具体原因修正输入;若消息目录或脚本缺失,再检查 Skill 文件完整性。\n');
80
+ process.stderr.write(`MESSAGE_RENDER_ERROR:${message}\n`);
81
+ return;
82
+ }
83
+ const prefixes = {
84
+ flow: 'FLOW_LOADER_ERROR:',
85
+ 'onboarding-message': 'ONBOARDING_MESSAGE_ERROR:',
86
+ 'integration-message': 'INTEGRATION_MESSAGE_ERROR:',
87
+ reply: 'ALIPAY_AIPAY_INTERNAL:REPLY_VALIDATION_ERROR=',
88
+ 'integration-context': 'ALIPAY_AIPAY_INTERNAL:INTEGRATION_CONTEXT_ERROR=',
89
+ 'onboarding-discovery': 'ALIPAY_AIPAY_INTERNAL:DISCOVERY_RUNNER_ERROR=',
90
+ 'onboarding-recovery': 'ALIPAY_AIPAY_INTERNAL:RECOVERY_RUNNER_ERROR=',
91
+ a2m: 'PYTHON_RUNNER_ERROR:'
92
+ };
93
+ process.stderr.write(`${prefixes[domain] || 'ALIPAY_AIPAY_INTERNAL:RUNTIME_ERROR='}${message}\n`);
94
+ }
95
+
96
+ function parseRuntimeArgs(args) {
97
+ const parsed = {};
98
+ for (let index = 0; index < args.length; index += 1) {
99
+ const token = args[index];
100
+ if (!token.startsWith('--')) throw new Error(`未知参数 ${token}`);
101
+ const value = args[index + 1];
102
+ if (value === undefined || value.startsWith('--')) throw new Error(`参数 ${token} 缺少取值`);
103
+ const name = token.slice(2);
104
+ if (Object.prototype.hasOwnProperty.call(parsed, name)) throw new Error(`参数 ${token} 重复`);
105
+ parsed[name] = value;
106
+ index += 1;
107
+ }
108
+ return parsed;
109
+ }
110
+
111
+ function requiredOption(options, name) {
112
+ const value = options[name];
113
+ if (typeof value !== 'string' || value.length === 0) throw new Error(`缺少参数 --${name}`);
114
+ return value;
115
+ }
116
+
117
+ function assertOnlyOptions(options, allowedNames) {
118
+ const allowed = new Set(allowedNames);
119
+ const unknown = Object.keys(options).filter((name) => !allowed.has(name));
120
+ if (unknown.length > 0) throw new Error(`未知参数 --${unknown[0]}`);
121
+ }
122
+
123
+ function assertEnumOption(options, name, allowedValues, { required = true } = {}) {
124
+ if (!Object.prototype.hasOwnProperty.call(options, name)) {
125
+ if (required) throw new Error(`缺少参数 --${name}`);
126
+ return '';
127
+ }
128
+ const value = requiredOption(options, name);
129
+ if (!allowedValues.includes(value)) {
130
+ throw new Error(`参数 --${name} 非法,仅支持 ${allowedValues.join('、')}`);
131
+ }
132
+ return value;
133
+ }
134
+
135
+ function applyTelemetryContext(domain, args) {
136
+ if (domain === 'telemetry') return args;
137
+ const remaining = [];
138
+ const values = {};
139
+ for (let index = 0; index < args.length; index += 1) {
140
+ const token = args[index];
141
+ if (token !== '--telemetry-run-id' && token !== '--telemetry-history-count') {
142
+ remaining.push(token);
143
+ continue;
144
+ }
145
+ const value = args[index + 1];
146
+ if (value === undefined || value.startsWith('--')) throw new Error(`参数 ${token} 缺少取值`);
147
+ if (Object.prototype.hasOwnProperty.call(values, token)) throw new Error(`参数 ${token} 重复`);
148
+ values[token] = value;
149
+ index += 1;
150
+ }
151
+ if (values['--telemetry-run-id'] !== undefined) {
152
+ process.env.ALIPAY_AIPAY_TELEMETRY_RUN_ID = values['--telemetry-run-id'];
153
+ } else {
154
+ const activeRun = currentRunContext(process.env);
155
+ if (activeRun && !activeRun.terminal) process.env.ALIPAY_AIPAY_TELEMETRY_RUN_ID = activeRun.run_id;
156
+ }
157
+ if (values['--telemetry-history-count'] !== undefined) {
158
+ const historyCount = values['--telemetry-history-count'];
159
+ if (historyCount !== 'null' && !/^(?:0|[1-9]\d*)$/u.test(historyCount)) {
160
+ throw new Error('--telemetry-history-count 只支持非负整数或 null');
161
+ }
162
+ process.env.ALIPAY_AIPAY_TELEMETRY_HISTORY_COUNT = historyCount;
163
+ } else if (!process.env.ALIPAY_AIPAY_TELEMETRY_HISTORY_COUNT) {
164
+ process.env.ALIPAY_AIPAY_TELEMETRY_HISTORY_COUNT = 'null';
165
+ }
166
+ return remaining;
167
+ }
168
+
169
+ async function runIntegrationBootstrap(args) {
170
+ const options = parseRuntimeArgs(args);
171
+ assertOnlyOptions(options, ['root-intent', 'product-type']);
172
+ const rootIntent = assertEnumOption(options, 'root-intent', ['integration_only']);
173
+ const productType = assertEnumOption(options, 'product-type', ['aipay', 'webpay', 'apppay'], { required: false });
174
+ process.env.ALIPAY_AIPAY_ROOT_INTENT = rootIntent;
175
+ await startTelemetryRun(rootIntent, productType);
176
+ const { runFlowCli } = await import('./flow_loader.mjs');
177
+ runFlowCli(cliArgv(['integration', 'entry']));
178
+ }
179
+
180
+ async function runOnboardingBootstrap(args) {
181
+ const options = parseRuntimeArgs(args);
182
+ assertOnlyOptions(options, ['root-intent', 'product-type']);
183
+ const rootIntent = assertEnumOption(options, 'root-intent', ['onboarding_only']);
184
+ const productType = assertEnumOption(options, 'product-type', ['aipay', 'webpay', 'apppay'], { required: false });
185
+ process.env.ALIPAY_AIPAY_ROOT_INTENT = rootIntent;
186
+ await startTelemetryRun(rootIntent, productType);
187
+ const { runOnboardingMessageCli } = await import('./onboarding_message_runner.mjs');
188
+ const platformEntryArgs = ['platform-entry'];
189
+ await runOnboardingMessageCli(cliArgv(platformEntryArgs));
190
+ const { isWindowsPlatform } = await import('./platform_compat.mjs');
191
+ if (isWindowsPlatform()) return;
192
+ const { runFlowCli } = await import('./flow_loader.mjs');
193
+ runFlowCli(cliArgv(['onboarding', 'entry']));
194
+ }
195
+
196
+ async function runOnboardingExecuteReady(args) {
197
+ const options = parseRuntimeArgs(args);
198
+ assertOnlyOptions(options, ['product-type']);
199
+ const productType = assertEnumOption(options, 'product-type', ['aipay', 'webpay', 'apppay']);
200
+ const { runFlowCli } = await import('./flow_loader.mjs');
201
+ runFlowCli(cliArgv(['onboarding', 'execute', '--product-type', productType]));
202
+ return dispatch('env', ['check', '--product-type', productType]);
203
+ }
204
+
205
+ async function dispatch(domain, args) {
206
+ if (domain === 'integration-bootstrap') return runIntegrationBootstrap(args);
207
+ if (domain === 'onboarding-bootstrap') return runOnboardingBootstrap(args);
208
+ if (domain === 'onboarding-execute-ready') return runOnboardingExecuteReady(args);
209
+ if (domain === 'auth') {
210
+ const [script, cwd] = shellPath(domain);
211
+ const { runAuthRuntime } = await import('./auth_runtime_runner.mjs');
212
+ process.exitCode = runAuthRuntime(script, cwd, args);
213
+ return;
214
+ }
215
+ if (shellEntrypoints[domain]) {
216
+ const [script, cwd] = shellPath(domain);
217
+ return runShell(script, cwd, args);
218
+ }
219
+ if (nodeEntrypoints[domain]) {
220
+ const [moduleName, exportName] = nodeEntrypoints[domain];
221
+ const result = await (await import(`./${moduleName}`))[exportName](cliArgv(args));
222
+ if (domain === 'telemetry') process.exitCode = result;
223
+ return;
224
+ }
225
+ if (domain === 'env') {
226
+ if (args[0] === 'refresh-alipay-cli') {
227
+ if (args.length !== 1) throw new Error('用法: runtime.mjs env refresh-alipay-cli');
228
+ const { runAlipayCliRefreshCli } = await import('./alipay_cli_refresh.mjs');
229
+ return runAlipayCliRefreshCli(cliArgv(['refresh-alipay-cli']));
230
+ }
231
+ if (args[0] === 'prepare-jq') {
232
+ if (args.length !== 1) throw new Error('用法: runtime.mjs env prepare-jq');
233
+ const { runManagedJqCli } = await import('./managed_jq.mjs');
234
+ process.exitCode = await runManagedJqCli(cliArgv(['prepare']));
235
+ return;
236
+ }
237
+ const { isWindowsPlatform } = await import('./platform_compat.mjs');
238
+ if (!isWindowsPlatform()) {
239
+ return runShell(path.join(scriptDir, 'alipay_cli_env.sh'), path.dirname(scriptDir), args);
240
+ }
241
+ const { runAlipayCliEnvCli } = await import('./alipay_cli_env.mjs');
242
+ return runAlipayCliEnvCli(cliArgv(args));
243
+ }
244
+ if (domain === 'self-update') {
245
+ const { runSelfUpdateCli } = await import('./self_update.mjs');
246
+ const outcome = await runSelfUpdateCli(cliArgv(args));
247
+ const version = outcome.version ? `=${outcome.version.raw}` : '';
248
+ process.stderr.write(`SELF_UPDATE:${outcome.kind}${version}\n`);
249
+ return;
250
+ }
251
+ if (domain === 'a2m') {
252
+ const { runPythonScriptCli } = await import('./python_script_runner.mjs');
253
+ const script = path.join(flowDirs.integration, 'modules/scripts/local_402_sandbox_pay.py');
254
+ return runPythonScriptCli(cliArgv([script, ...args]));
255
+ }
256
+ throw new Error(`用法: runtime.mjs <${runtimeDomains.join('|')}> ...`);
257
+ }
258
+
259
+ export async function runRuntimeCli(argv = process.argv) {
260
+ const domain = argv[2] || '';
261
+ try {
262
+ await dispatch(domain, applyTelemetryContext(domain, applyTelemetrySession(applyAgentPlatform(argv.slice(3)))));
263
+ } catch (error) {
264
+ runtimeError(domain, error);
265
+ process.exitCode = domain === 'self-update' ? 0 : 1;
266
+ }
267
+ }
268
+
269
+ if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
270
+ runRuntimeCli();
271
+ }
@@ -0,0 +1,376 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { spawn, spawnSync } from 'node:child_process';
4
+ import { randomUUID } from 'node:crypto';
5
+ import fs from 'node:fs';
6
+ import path from 'node:path';
7
+ import process from 'node:process';
8
+ import { setTimeout as delay } from 'node:timers/promises';
9
+ import { fileURLToPath } from 'node:url';
10
+
11
+ const scriptDir = path.dirname(fileURLToPath(import.meta.url));
12
+ const defaultSkillDir = path.resolve(scriptDir, '../../..');
13
+ const npmQueryTimeoutMs = 5 * 1000;
14
+ const installTimeoutMs = 60 * 1000;
15
+ const outputLimitBytes = 64 * 1024;
16
+ const selfUpdateTargetEnv = 'ALIPAY_AIPAY_SELF_UPDATE_TARGET';
17
+ const selfUpdateTransactionEnv = 'ALIPAY_AIPAY_SELF_UPDATE_TRANSACTION';
18
+
19
+ function installTimeoutBudget() {
20
+ if (process.env.ALIPAY_AIPAY_TEST_MODE !== '1') return installTimeoutMs;
21
+ const value = Number(process.env.ALIPAY_AIPAY_SELF_UPDATE_TEST_INSTALL_TIMEOUT_MS);
22
+ return Number.isInteger(value) && value >= 50 && value <= installTimeoutMs ? value : installTimeoutMs;
23
+ }
24
+
25
+ function appendBounded(current, chunk) {
26
+ const combined = current + chunk.toString('utf8');
27
+ return combined.length > outputLimitBytes ? combined.slice(-outputLimitBytes) : combined;
28
+ }
29
+
30
+ async function terminateProcessTree(child) {
31
+ if (!child.pid) return;
32
+ if (process.platform === 'win32') {
33
+ spawnSync('taskkill.exe', ['/pid', String(child.pid), '/t', '/f'], {
34
+ stdio: 'ignore',
35
+ timeout: 2 * 1000,
36
+ windowsHide: true,
37
+ });
38
+ try { child.kill('SIGKILL'); } catch {}
39
+ return;
40
+ }
41
+
42
+ try { process.kill(-child.pid, 'SIGTERM'); } catch {}
43
+ await delay(250);
44
+ try { process.kill(-child.pid, 'SIGKILL'); } catch {}
45
+ }
46
+
47
+ function packageManagerCommand(command, args) {
48
+ if (process.platform !== 'win32') return { command, args, detached: true };
49
+
50
+ const allowedCommands = new Set(['npm', 'npx']);
51
+ const safeToken = /^[A-Za-z0-9@./=+_-]+$/u;
52
+ if (!allowedCommands.has(command) || args.some((arg) => !safeToken.test(arg))) {
53
+ throw new Error('unsafe Windows package-manager command');
54
+ }
55
+ return {
56
+ command: process.env.ComSpec || 'cmd.exe',
57
+ args: ['/d', '/s', '/c', [`${command}.cmd`, ...args].join(' ')],
58
+ detached: false,
59
+ };
60
+ }
61
+
62
+ function spawnPackageManager(command, args, { timeout, env = process.env }) {
63
+ return new Promise((resolve) => {
64
+ let invocation;
65
+ try {
66
+ invocation = packageManagerCommand(command, args);
67
+ } catch (error) {
68
+ resolve({ status: null, signal: null, stdout: '', stderr: '', error });
69
+ return;
70
+ }
71
+
72
+ let child;
73
+ try {
74
+ child = spawn(invocation.command, invocation.args, {
75
+ detached: invocation.detached,
76
+ env,
77
+ stdio: ['ignore', 'pipe', 'pipe'],
78
+ windowsHide: true,
79
+ });
80
+ } catch (error) {
81
+ resolve({ status: null, signal: null, stdout: '', stderr: '', error });
82
+ return;
83
+ }
84
+
85
+ let stdout = '';
86
+ let stderr = '';
87
+ let finished = false;
88
+ let timedOut = false;
89
+ let closed = false;
90
+ let timer;
91
+ let closeResolve;
92
+ const closedPromise = new Promise((done) => { closeResolve = done; });
93
+
94
+ child.stdout?.on('data', (chunk) => { stdout = appendBounded(stdout, chunk); });
95
+ child.stderr?.on('data', (chunk) => { stderr = appendBounded(stderr, chunk); });
96
+
97
+ const finish = (result) => {
98
+ if (finished) return;
99
+ finished = true;
100
+ clearTimeout(timer);
101
+ resolve({ ...result, stdout, stderr });
102
+ };
103
+
104
+ child.once('error', (error) => {
105
+ if (!timedOut) finish({ status: null, signal: null, error });
106
+ });
107
+ child.once('close', (status, signal) => {
108
+ closed = true;
109
+ closeResolve();
110
+ if (!timedOut) finish({ status, signal, error: null });
111
+ });
112
+
113
+ timer = setTimeout(() => {
114
+ timedOut = true;
115
+ void (async () => {
116
+ await terminateProcessTree(child);
117
+ if (!closed) await Promise.race([closedPromise, delay(2 * 1000)]);
118
+ const error = new Error(`package manager timed out after ${timeout}ms`);
119
+ error.code = 'ETIMEDOUT';
120
+ finish({ status: null, signal: 'SIGKILL', error });
121
+ })();
122
+ }, timeout);
123
+ });
124
+ }
125
+
126
+ function isRegularFile(file) {
127
+ try {
128
+ const stat = fs.lstatSync(file);
129
+ return stat.isFile() && !stat.isSymbolicLink();
130
+ } catch {
131
+ return false;
132
+ }
133
+ }
134
+
135
+ function isRecoverableSkillRoot(skillDir) {
136
+ try {
137
+ const root = fs.lstatSync(skillDir);
138
+ return root.isDirectory()
139
+ && !root.isSymbolicLink()
140
+ && isRegularFile(path.join(skillDir, 'SKILL.md'))
141
+ && isRegularFile(path.join(skillDir, 'references', 'normal', 'scripts', 'self_update.mjs'));
142
+ } catch {
143
+ return false;
144
+ }
145
+ }
146
+
147
+ function parseArgs(argv) {
148
+ if (argv[2] !== 'check') throw new Error('用法: self_update.mjs check [--skill-dir <absolutePath>]');
149
+ let skillDir = defaultSkillDir;
150
+ for (let index = 3; index < argv.length; index += 1) {
151
+ if (argv[index] === '--skill-dir' && argv[index + 1]) {
152
+ skillDir = argv[index + 1];
153
+ index += 1;
154
+ continue;
155
+ }
156
+ throw new Error(`未知参数 ${argv[index]}`);
157
+ }
158
+ if (!path.isAbsolute(skillDir)) throw new Error('--skill-dir 必须是绝对路径');
159
+ const resolved = fs.realpathSync(skillDir);
160
+ const currentRoot = fs.realpathSync(defaultSkillDir);
161
+ if (resolved !== currentRoot || !isRecoverableSkillRoot(resolved)) {
162
+ throw new Error('--skill-dir 必须绑定当前运行中的 Skill 根目录');
163
+ }
164
+ return resolved;
165
+ }
166
+
167
+ function parseVersion(value) {
168
+ const raw = value.trim().replace(/^v/u, '');
169
+ const match = raw.match(/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/u);
170
+ if (!match || raw.length > 256) return null;
171
+ const prerelease = match[4]?.split('.') || [];
172
+ const build = raw.includes('+') ? raw.split('+')[1].split('.') : [];
173
+ if (![match[1], match[2], match[3]].every((value) => Number.isSafeInteger(Number(value)))) return null;
174
+ if (prerelease.some((value) => !value || (/^\d+$/u.test(value) && value.length > 1 && value[0] === '0'))) return null;
175
+ if (build.some((value) => !value)) return null;
176
+ return { raw, major: Number(match[1]), minor: Number(match[2]), patch: Number(match[3]), prerelease };
177
+ }
178
+
179
+ function compareIdentifiers(left, right) {
180
+ const leftNumeric = /^\d+$/u.test(left);
181
+ const rightNumeric = /^\d+$/u.test(right);
182
+ if (leftNumeric && rightNumeric) return Number(left) - Number(right);
183
+ if (leftNumeric !== rightNumeric) return leftNumeric ? -1 : 1;
184
+ return left.localeCompare(right);
185
+ }
186
+
187
+ function compareVersions(left, right) {
188
+ for (const key of ['major', 'minor', 'patch']) {
189
+ if (left[key] !== right[key]) return left[key] - right[key];
190
+ }
191
+ if (left.prerelease.length === 0 || right.prerelease.length === 0) {
192
+ return left.prerelease.length === right.prerelease.length ? 0 : left.prerelease.length === 0 ? 1 : -1;
193
+ }
194
+ for (let index = 0; index < Math.max(left.prerelease.length, right.prerelease.length); index += 1) {
195
+ if (left.prerelease[index] === undefined) return -1;
196
+ if (right.prerelease[index] === undefined) return 1;
197
+ const compared = compareIdentifiers(left.prerelease[index], right.prerelease[index]);
198
+ if (compared !== 0) return compared;
199
+ }
200
+ return 0;
201
+ }
202
+
203
+ export function skillVersionKind(value, channel) {
204
+ if (typeof value !== 'string') return null;
205
+ const parsed = parseVersion(value);
206
+ if (!parsed) return null;
207
+ const suffix = parsed.prerelease.join('.');
208
+ if (suffix === (channel === 'pre' ? 'pre' : '')) return 'release';
209
+ const pattern = channel === 'pre' ? /^pre-beta(?:\d+|\.\d+)?$/u : /^beta(?:\d+|\.\d+)?$/u;
210
+ return pattern.test(suffix) ? 'beta' : null;
211
+ }
212
+
213
+ function readVersionFile(skillDir) {
214
+ try {
215
+ const file = path.join(skillDir, 'VERSION');
216
+ return isRegularFile(file) ? parseVersion(fs.readFileSync(file, 'utf8')) : null;
217
+ } catch {
218
+ return null;
219
+ }
220
+ }
221
+
222
+ function readLocalVersion(skillDir) {
223
+ try {
224
+ const versionFile = path.join(skillDir, 'VERSION');
225
+ const skillFile = path.join(skillDir, 'SKILL.md');
226
+ const runtimeEntry = path.join(skillDir, 'references', 'runtime-entry.md');
227
+ if (![versionFile, skillFile, runtimeEntry].every(isRegularFile)) return null;
228
+ return parseVersion(fs.readFileSync(versionFile, 'utf8'));
229
+ } catch {
230
+ return null;
231
+ }
232
+ }
233
+
234
+ function selfUpdateNetworkRestricted() {
235
+ return /^(1|true|yes|on)$/iu.test(process.env.ALIPAY_AIPAY_SELF_UPDATE_NETWORK_RESTRICTED || '');
236
+ }
237
+
238
+ function packageManagerFailureKind(result) {
239
+ if (result?.error?.code === 'ENOENT') return 'local';
240
+ const raw = [
241
+ result?.error?.code,
242
+ result?.error?.message,
243
+ result?.stderr,
244
+ result?.stdout,
245
+ ].filter(Boolean).join('\n');
246
+ if (/ETIMEDOUT|ESOCKETTIMEDOUT|ENOTFOUND|EAI_AGAIN|ECONN(?:RESET|REFUSED|ABORTED)|EHOSTUNREACH|ENETUNREACH|network access[^]*(?:denied|blocked)|getaddrinfo|could not resolve|fetch failed|socket hang up|TLS handshake|503 Service Unavailable|502 Bad Gateway|504 Gateway Timeout/iu.test(raw)) {
247
+ return 'network';
248
+ }
249
+ return 'check';
250
+ }
251
+
252
+ function readChannel(skillDir) {
253
+ const source = fs.readFileSync(path.join(skillDir, 'SKILL.md'), 'utf8');
254
+ const declaredName = source.match(/^name:\s*(\S+)\s*$/m)?.[1];
255
+ const identity = declaredName === 'alipay-aipay-pre' ? 'pre' : 'stable';
256
+ const channelFile = path.join(skillDir, 'references', 'normal', 'json', 'release-channel.json');
257
+ if (!fs.existsSync(channelFile) && identity === 'stable') return 'stable';
258
+ if (!isRegularFile(channelFile)) throw new Error('invalid release channel');
259
+ const channel = JSON.parse(fs.readFileSync(channelFile, 'utf8')).channel;
260
+ if (!['stable', 'pre'].includes(channel) || channel !== identity) throw new Error('invalid release channel');
261
+ return channel;
262
+ }
263
+
264
+ async function npmLatest(channel) {
265
+ if (selfUpdateNetworkRestricted()) return { ok: false, reason: 'skipped-network-restricted' };
266
+ try {
267
+ const result = await spawnPackageManager('npm', ['view', '@alipay/alipay-aipay@latest', 'version', 'alipayAipayChannels', '--json'], {
268
+ timeout: npmQueryTimeoutMs,
269
+ });
270
+ if (result.status !== 0 || result.error) return { ok: false, reason: packageManagerFailureKind(result) };
271
+ const decoded = JSON.parse(result.stdout);
272
+ const packageVersion = typeof decoded?.version === 'string' ? parseVersion(decoded.version) : null;
273
+ const value = decoded?.alipayAipayChannels?.[channel];
274
+ const version = typeof value === 'string' ? parseVersion(value) : null;
275
+ return packageVersion && version && skillVersionKind(version.raw, channel) === 'release' ? { ok: true, version, packageVersion } : { ok: false, reason: 'check' };
276
+ } catch {
277
+ return { ok: false, reason: 'check' };
278
+ }
279
+ }
280
+
281
+ function transactionArtifacts(skillDir, transactionId, channel) {
282
+ const parent = path.dirname(skillDir);
283
+ const skillName = channel === 'pre' ? 'alipay-aipay-pre' : 'alipay-aipay';
284
+ return {
285
+ staging: path.join(parent, `.${skillName}-install-${transactionId}`),
286
+ backup: path.join(parent, `.${skillName}-backup-${transactionId}`),
287
+ };
288
+ }
289
+
290
+ function removeTransactionPath(target) {
291
+ try { fs.rmSync(target, { recursive: true, force: true }); } catch {}
292
+ }
293
+
294
+ function reconcileInstallTransaction(skillDir, transactionId, channel) {
295
+ const artifacts = transactionArtifacts(skillDir, transactionId, channel);
296
+ let current = readLocalVersion(skillDir);
297
+ if (!current && isRecoverableSkillRoot(artifacts.backup)) {
298
+ try {
299
+ removeTransactionPath(skillDir);
300
+ fs.renameSync(artifacts.backup, skillDir);
301
+ } catch {}
302
+ current = readLocalVersion(skillDir);
303
+ }
304
+ removeTransactionPath(artifacts.staging);
305
+ if (isRecoverableSkillRoot(skillDir)) removeTransactionPath(artifacts.backup);
306
+ return current;
307
+ }
308
+
309
+ async function installVersion(skillDir, packageVersion, channel) {
310
+ const transactionId = randomUUID();
311
+ const timeout = installTimeoutBudget();
312
+ let result;
313
+ try {
314
+ result = await spawnPackageManager(
315
+ 'npx',
316
+ ['-y', `@alipay/alipay-aipay@${packageVersion.raw}`, 'install-current', '--channel', channel],
317
+ {
318
+ timeout,
319
+ env: {
320
+ ...process.env,
321
+ [selfUpdateTargetEnv]: skillDir,
322
+ [selfUpdateTransactionEnv]: transactionId,
323
+ },
324
+ },
325
+ );
326
+ } catch {
327
+ result = { status: null, error: new Error('package manager check failed'), stdout: '', stderr: '' };
328
+ }
329
+ return {
330
+ ok: result.status === 0 && !result.error,
331
+ reason: result.status === 0 && !result.error ? 'ok' : packageManagerFailureKind(result),
332
+ version: reconcileInstallTransaction(skillDir, transactionId, channel),
333
+ };
334
+ }
335
+
336
+ function reportOutcome(outcome) {
337
+ const version = outcome.version ? `=${outcome.version.raw}` : '';
338
+ process.stderr.write(`SELF_UPDATE:${outcome.kind}${version}\n`);
339
+ }
340
+
341
+ export async function runSelfUpdateCli(argv = process.argv) {
342
+ const skillDir = parseArgs(argv);
343
+ const channel = readChannel(skillDir);
344
+ const local = readLocalVersion(skillDir);
345
+ const installedVersion = readVersionFile(skillDir);
346
+ const kind = skillVersionKind(installedVersion?.raw, channel);
347
+ // A developer-installed beta is pinned, including when its entry is damaged.
348
+ if (kind === 'beta') return local ? { kind: 'CURRENT', version: local } : { kind: 'VERIFY_FAILED' };
349
+ if (installedVersion && !kind) return { kind: 'CHECK_FAILED' };
350
+ const checked = await npmLatest(channel);
351
+ if (!checked.ok) {
352
+ const current = readLocalVersion(skillDir);
353
+ if (current && (!local || compareVersions(current, local) > 0)) return { kind: 'UPDATED', version: current };
354
+ if (checked.reason === 'skipped-network-restricted') return { kind: 'SKIPPED_NETWORK_RESTRICTED' };
355
+ if (checked.reason === 'network') return { kind: 'RETRY_WITH_NETWORK' };
356
+ return { kind: 'CHECK_FAILED' };
357
+ }
358
+
359
+ const latest = checked.version;
360
+ if (local && compareVersions(local, latest) >= 0) return { kind: 'CURRENT', version: local };
361
+
362
+ const installed = await installVersion(skillDir, checked.packageVersion, channel);
363
+ const updated = installed.version || readLocalVersion(skillDir);
364
+ if (updated && readChannel(skillDir) === channel && compareVersions(updated, latest) >= 0) return { kind: 'UPDATED', version: updated };
365
+ if (installed.reason === 'network') return { kind: 'RETRY_WITH_NETWORK' };
366
+ if (installed.reason === 'local') return { kind: 'CHECK_FAILED' };
367
+ return { kind: installed.ok ? 'VERIFY_FAILED' : 'INSTALL_FAILED' };
368
+ }
369
+
370
+ if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
371
+ try {
372
+ reportOutcome(await runSelfUpdateCli());
373
+ } catch {
374
+ reportOutcome({ kind: 'CHECK_FAILED' });
375
+ }
376
+ }