@alipay/alipay-aipay 1.5.8-beta2 → 1.5.8-beta3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skill/VERSION +1 -1
- package/skill/references/onboarding/flow.md +2 -0
- package/skill/references/onboarding/modules/authorization.md +1 -0
- package/skill/references/onboarding/modules/error-handling.md +2 -2
- package/skill/references/onboarding/modules/scripts/app.sh +6 -6
- package/skill/references/onboarding/modules/scripts/ar_sign_apply.sh +1 -1
- package/skill/references/onboarding/modules/scripts/auth.sh +4 -1
- package/skill/references/onboarding/modules/scripts/error_handler.sh +92 -3
- package/skill/references/onboarding/modules/scripts/query_sign_status.sh +1 -1
- package/skill/references/onboarding/modules/scripts/service.sh +2 -2
- package/skill/references/onboarding/modules/scripts/upload_screenshots.sh +3 -3
package/package.json
CHANGED
package/skill/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.5.8-
|
|
1
|
+
1.5.8-beta3
|
|
@@ -203,6 +203,7 @@ Step 1 的产品/MCC 唯一事实校验和方案送达、Step 2 的环境 READY
|
|
|
203
203
|
├─ AUTH_FLOW:READY_TO_OPEN → 输出非阻塞授权页,执行第 2 项
|
|
204
204
|
│ └─ 若同时存在 AUTH_STATE:SAVE_FAILED:授权页 stdout 已送达,后续 open 仅可降级为 AUTH_OPEN:LINK_ONLY;wait/confirm 仍使用本条命令显式上下文继续,禁止重新生成授权页
|
|
205
205
|
├─ 底层 init 命中 SCOPE_MISMATCH / MCC_MISMATCH → runtime 在同一命令内自动调用既有第 4 项,只透传 mismatch 的最终结果;唯一 AUTH_AUTO_MISMATCH 仅供内部诊断,不是终态
|
|
206
|
+
├─ AUTH_FLOW:AUTH_REQUIRED → 当前失效会话已按脚本后置条件处理;原样重新执行第 1 项一次,生成当前上下文的新授权页;再次命中则停止循环
|
|
206
207
|
├─ AUTH_FLOW:RETRY_WITH_NETWORK → 取得联网权限后重试同一完整命令
|
|
207
208
|
├─ AUTH_FLOW:RETRY_WITH_LOCAL_FS_PERMISSION → 取得 CLI 私有状态目录权限后原样重试本命令一次
|
|
208
209
|
├─ AUTH_FLOW:LOGOUT_STILL_LOGGED_IN → 自动 mismatch 的 logout 后置条件未成立,按第 4 项同名分支停止
|
|
@@ -216,6 +217,7 @@ Step 1 的产品/MCC 唯一事实校验和方案送达、Step 2 的环境 READY
|
|
|
216
217
|
├─ AUTH_FLOW:PENDING → 输出 auth.pending,等待用户明确表示扫码已完成
|
|
217
218
|
├─ AUTH_FLOW:EXPIRED → 重新执行第 1 项生成授权链接
|
|
218
219
|
├─ AUTH_FLOW:CONTEXT_MISMATCH → 当前动作未执行 login --complete/logout;使用当前已确认的完整参数重新执行第 1 项
|
|
220
|
+
├─ AUTH_FLOW:AUTH_REQUIRED → 当前授权会话已失效,旧页面不再作为恢复依据;原样重新执行第 1 项一次,再次命中则停止循环
|
|
219
221
|
├─ AUTH_FLOW:RETRY_WITH_NETWORK → 取得联网权限后重试同一完整命令
|
|
220
222
|
├─ AUTH_FLOW:RETRY_WITH_LOCAL_FS_PERMISSION → 保留当前授权页短时状态,取得 CLI 私有状态目录权限后原样重试当前 wait 命令一次
|
|
221
223
|
├─ AUTH_FLOW:FAILED → 停止并按错误输出恢复,禁止进入 Step 3.1
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
- `AUTH_FLOW:PENDING`:有限轮询耗尽或单次恢复查询尚未得到有效本机登录态;不等于失败,也不证明用户未扫码。
|
|
23
23
|
- `AUTH_FLOW:EXPIRED`:当前页面实际返回过期,旧页面和旧回复失效,重新执行 flow 登记的 init。
|
|
24
24
|
- `AUTH_FLOW:SCOPE_MISMATCH|MCC_MISMATCH`:只能走 `auth.sh mismatch`。统一 runtime 的 `auth init` 在底层 init 唯一返回 mismatch 且 stdout 为空时,会在同一命令内自动调用既有 `auth.sh mismatch`,抑制中间 mismatch 终态并只透传最终结果;`wait|confirm` 返回 mismatch 时仍按 flow 显式调用 mismatch。logout 后置条件未成立前不得重授权;仍登录返回 `AUTH_FLOW:LOGOUT_STILL_LOGGED_IN`。
|
|
25
|
+
- `AUTH_FLOW:AUTH_REQUIRED`:`whoami` 或已认证资源校验已证明当前 CLI 会话失效,且脚本已完成既有 logout 后置条件处理;按 flow 原样重新执行当前上下文的 `auth init` 一次,旧授权页不再作为恢复依据,再次命中时停止循环。
|
|
25
26
|
- `AUTH_FLOW:RETRY_WITH_NETWORK`:当前 Agent 环境无法确认结果,申请联网权限后原样重试同一命令;不得解释为用户本机登录失败。
|
|
26
27
|
- `AUTH_FLOW:RETRY_WITH_LOCAL_FS_PERMISSION`:授权状态命令 preflight 失败,或实际输出命中 CLI 私有状态写失败证据。可恢复阶段 stdout 为空;仅允许当前受控 runtime 命令访问 CLI 私有状态目录后原样重试一次;`wait|confirm` 保留短时授权状态,不重建授权页。Agent 禁止读取、列举、打印或复制已有凭据与日志;拒绝、不支持或重试仍命中同一 marker 时才输出最小失败说明。
|
|
27
28
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
| 内部分类 | 已验证触发 | 恢复边界 |
|
|
8
8
|
| --- | --- | --- |
|
|
9
|
-
| `MCP_AUTH_ERROR` | HTTP 401、`Authorization is empty
|
|
9
|
+
| `MCP_AUTH_ERROR` | HTTP 401、`Authorization is empty`、非法认证信息、`用户未登录`、`not_logged_in` 等明确登录失效证据;已认证资源动作顶层或 `data.logged_in=false` | 停止查询组;logout 后置条件成立后重授权。仍登录则阻断;不可确认或无网络时只重试同一动作,不解释为用户本机或支付宝业务失败 |
|
|
10
10
|
| `AUTH_MISMATCH` | `mccCode is not auth`、`salesProductCodes is not auth`、`scope is not auth` | 停止当前动作,只进 `auth.sh mismatch`;logout 后置条件未成立前禁重授权 |
|
|
11
11
|
| `MCP_SERVICE_ERROR` / `SERVICE_UNSTABLE` | 已识别连接、网络或服务异常 | 按下方有限重试规则处理;耗尽后记录受影响分支,依赖允许时继续其他独立分支,最终统一收口 |
|
|
12
12
|
| `DISCOVERY_FLOW:RETRY_WITH_NETWORK` | discovery 子查询重试耗尽,且原始输出包含 DNS、连接、timeout、socket/TLS、`fetch failed`、`network_error`、`网络连接失败` 或连接前沙箱禁网强证据 | 只在无授权阻断时输出一次;暂存首次 stdout,申请联网权限后原样重试同一 discovery 命令一次。拒绝、不支持或再次命中时停止申请,只送达最新一次既有 stdout |
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
| `CLI_ERROR:<message>` | CLI 失败、异常结构或结果不可唯一解析 | 隐藏原始输出,停止并按登记 CLI 错误恢复,不猜成功或空结果 |
|
|
18
18
|
| `SUCCESS` | 唯一合法成功结构 | 才允许进入当前脚本的业务字段解析 |
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
发现阶段的单分支失败不得伪装为空列表,也不得回滚其他已成功分支;认证失效或授权不匹配属于查询组全局阻断,重新授权后恢复尚未执行的查询,主体一致性无法确认时重新查询全部适用状态。`logged_in=false` 只在已认证的签约、服务、应用和上传等资源动作中属于认证失效;`auth.sh whoami` 的成功未登录结果仍是正常登录入口,失败响应即使携带该字段也不能证明已退出。
|
|
21
21
|
|
|
22
22
|
discovery runner 和截图上传这类并发/分组动作不得让每个子进程各自 logout。子脚本在分组环境下只上报认证失效事实;由 flow 登记的唯一授权恢复入口执行一次 logout 后置条件确认。三张截图同时认证失败时只允许产生一个全局认证恢复 marker。
|
|
23
23
|
|
|
@@ -324,7 +324,7 @@ query_security_key() {
|
|
|
324
324
|
return 1
|
|
325
325
|
fi
|
|
326
326
|
|
|
327
|
-
if ! handle_error "$RESULT"; then
|
|
327
|
+
if ! handle_error "$RESULT" "MCP_AUTHENTICATED_CALL"; then
|
|
328
328
|
return 1
|
|
329
329
|
fi
|
|
330
330
|
|
|
@@ -353,7 +353,7 @@ query_application_info() {
|
|
|
353
353
|
return 1
|
|
354
354
|
fi
|
|
355
355
|
|
|
356
|
-
if ! handle_error "$RESULT"; then
|
|
356
|
+
if ! handle_error "$RESULT" "MCP_AUTHENTICATED_CALL"; then
|
|
357
357
|
return 1
|
|
358
358
|
fi
|
|
359
359
|
|
|
@@ -590,7 +590,7 @@ app_list() {
|
|
|
590
590
|
fi
|
|
591
591
|
|
|
592
592
|
# 错误检测
|
|
593
|
-
if ! handle_error "$RESULT"; then
|
|
593
|
+
if ! handle_error "$RESULT" "MCP_AUTHENTICATED_CALL"; then
|
|
594
594
|
exit 1
|
|
595
595
|
fi
|
|
596
596
|
|
|
@@ -701,7 +701,7 @@ app_create() {
|
|
|
701
701
|
fi
|
|
702
702
|
|
|
703
703
|
# 错误检测
|
|
704
|
-
if ! handle_error "$RESULT"; then
|
|
704
|
+
if ! handle_error "$RESULT" "MCP_AUTHENTICATED_CALL"; then
|
|
705
705
|
emit_control "APPLICATION_CREATE_RESULT=FAILED"
|
|
706
706
|
exit 1
|
|
707
707
|
fi
|
|
@@ -782,7 +782,7 @@ app_key() {
|
|
|
782
782
|
fi
|
|
783
783
|
|
|
784
784
|
# 错误检测
|
|
785
|
-
if ! handle_error "$RESULT"; then
|
|
785
|
+
if ! handle_error "$RESULT" "MCP_AUTHENTICATED_CALL"; then
|
|
786
786
|
emit_control "KEY_PAGE_RESULT=FAILED"
|
|
787
787
|
exit 1
|
|
788
788
|
fi
|
|
@@ -900,7 +900,7 @@ submit_application_audit() {
|
|
|
900
900
|
fi
|
|
901
901
|
|
|
902
902
|
# 错误检测
|
|
903
|
-
if ! handle_error "$RESULT"; then
|
|
903
|
+
if ! handle_error "$RESULT" "MCP_AUTHENTICATED_CALL"; then
|
|
904
904
|
emit_control "APPLICATION_AUDIT_RESULT=FAILED"
|
|
905
905
|
exit 1
|
|
906
906
|
fi
|
|
@@ -529,9 +529,12 @@ validate_current_authorization() {
|
|
|
529
529
|
}
|
|
530
530
|
|
|
531
531
|
mcc_verify_unwrapped=$(unwrap_mcp "$mcc_verify_result")
|
|
532
|
-
mcc_error_type=$(detect_error "$mcc_verify_result")
|
|
532
|
+
mcc_error_type=$(detect_error "$mcc_verify_result" "MCP_AUTHENTICATED_CALL")
|
|
533
533
|
if [ "$mcc_error_type" = "AUTH_MISMATCH" ]; then
|
|
534
534
|
mcc_match="false"
|
|
535
|
+
elif [ "$mcc_error_type" = "MCP_AUTH_ERROR" ]; then
|
|
536
|
+
handle_error "$mcc_verify_result" "MCP_AUTHENTICATED_CALL" || true
|
|
537
|
+
return 1
|
|
535
538
|
elif [ "$mcc_error_type" != "SUCCESS" ]; then
|
|
536
539
|
echo "❌ MCC 校验失败"
|
|
537
540
|
emit_control "AUTH_FLOW:FAILED"
|
|
@@ -322,9 +322,11 @@ extract_checked_errors() {
|
|
|
322
322
|
|
|
323
323
|
# ─── 统一错误检测 ──────────────────────────────────────────────────────────
|
|
324
324
|
# 参数: $1 - CLI 执行结果文本(原始输出,含信封或不含)
|
|
325
|
+
# $2 - 可选调用上下文;MCP_AUTHENTICATED_CALL 允许识别资源响应中的明确未登录状态
|
|
325
326
|
# 返回: MCP_AUTH_ERROR | MCP_SERVICE_ERROR | AUTH_MISMATCH | SERVICE_UNSTABLE | CLI_LOCAL_FS_PERMISSION | ERROR:xxx | CLI_ERROR:xxx | SUCCESS
|
|
326
327
|
detect_error() {
|
|
327
328
|
local CLI_RESULT="$1"
|
|
329
|
+
local ERROR_CONTEXT="${2:-}"
|
|
328
330
|
|
|
329
331
|
# 空输入视为异常,不应被当作 SUCCESS
|
|
330
332
|
if [ -z "$CLI_RESULT" ]; then
|
|
@@ -340,8 +342,93 @@ detect_error() {
|
|
|
340
342
|
# 先解包 MCP 信封,再进行错误检测
|
|
341
343
|
local UNWRAPPED=$(unwrap_mcp "$CLI_RESULT")
|
|
342
344
|
|
|
343
|
-
# 1. 优先检测 MCP
|
|
344
|
-
|
|
345
|
+
# 1. 优先检测 MCP 认证错误。保留既有强证据;新增中文和 token 证据
|
|
346
|
+
# 仅扫描失败形态,避免成功候选名称或描述中的同名文本触发误判。
|
|
347
|
+
if echo "$UNWRAPPED" | grep -qiE \
|
|
348
|
+
"HTTP[[:space:]]*401|Authorization is empty|非法的认证信息"; then
|
|
349
|
+
echo "MCP_AUTH_ERROR"
|
|
350
|
+
return
|
|
351
|
+
fi
|
|
352
|
+
|
|
353
|
+
local AUTH_FAILURE_SHAPED=false
|
|
354
|
+
if ! echo "$UNWRAPPED" | jq -e . >/dev/null 2>&1 ||
|
|
355
|
+
echo "$UNWRAPPED" | jq -e '
|
|
356
|
+
(type == "object") and (
|
|
357
|
+
any(.. | objects; .success? == false) or
|
|
358
|
+
(.error? != null) or
|
|
359
|
+
(.errorCode? != null) or
|
|
360
|
+
((.errorMessage? | type) == "string" and .errorMessage != "") or
|
|
361
|
+
((.errorMsg? | type) == "string" and .errorMsg != "") or
|
|
362
|
+
(((.code? // "") | tostring) as $code |
|
|
363
|
+
$code != "" and $code != "0" and $code != "10000") or
|
|
364
|
+
any(.. | objects; (.error? != null) or (.errorCode? != null))
|
|
365
|
+
)
|
|
366
|
+
' >/dev/null 2>&1; then
|
|
367
|
+
AUTH_FAILURE_SHAPED=true
|
|
368
|
+
fi
|
|
369
|
+
if [ "$AUTH_FAILURE_SHAPED" = "true" ] &&
|
|
370
|
+
echo "$UNWRAPPED" | grep -qiE \
|
|
371
|
+
"用户未登录|not[ _-]+logged[ _-]+in|(authorization|authentication|login)[-[:space:]_:=]+(is[-[:space:]_:=]+)?required|(access|auth|authentication|authorization)[ _-]+token[-[:space:]_:=]+(is[-[:space:]_:=]+)?(missing|expired)|(missing|expired)[-[:space:]_:=]+(access|auth|authentication|authorization)[ _-]+token"; then
|
|
372
|
+
echo "MCP_AUTH_ERROR"
|
|
373
|
+
return
|
|
374
|
+
fi
|
|
375
|
+
|
|
376
|
+
if echo "$UNWRAPPED" | jq -e --arg context "$ERROR_CONTEXT" '
|
|
377
|
+
def is_auth_code:
|
|
378
|
+
type == "string" and (
|
|
379
|
+
ascii_downcase as $code |
|
|
380
|
+
[
|
|
381
|
+
"not_logged_in",
|
|
382
|
+
"login_required",
|
|
383
|
+
"unauthenticated",
|
|
384
|
+
"authorization_required",
|
|
385
|
+
"auth_required",
|
|
386
|
+
"access_token_missing",
|
|
387
|
+
"access_token_expired",
|
|
388
|
+
"auth_token_missing",
|
|
389
|
+
"auth_token_expired"
|
|
390
|
+
] |
|
|
391
|
+
index($code) != null
|
|
392
|
+
);
|
|
393
|
+
[
|
|
394
|
+
.code?, .errorCode?, .status?, .reason?,
|
|
395
|
+
(.error? | objects | (.code?, .errorCode?, .status?, .reason?)),
|
|
396
|
+
(.. | objects | .error? | objects | (.code?, .errorCode?, .status?, .reason?)),
|
|
397
|
+
(
|
|
398
|
+
.. | objects | select(has("errorCode")) | .errorCode? |
|
|
399
|
+
if type == "object" then (.code?, .status?, .reason?) else . end
|
|
400
|
+
)
|
|
401
|
+
] +
|
|
402
|
+
(
|
|
403
|
+
if any(.. | objects; .success? == false) then
|
|
404
|
+
[.. | objects | (.code?, .status?, .reason?)]
|
|
405
|
+
else
|
|
406
|
+
[]
|
|
407
|
+
end
|
|
408
|
+
) +
|
|
409
|
+
(
|
|
410
|
+
if $context == "MCP_AUTHENTICATED_CALL" and (.data? | type) == "object" then
|
|
411
|
+
[.data.code?, .data.status?, .data.reason?]
|
|
412
|
+
else
|
|
413
|
+
[]
|
|
414
|
+
end
|
|
415
|
+
) |
|
|
416
|
+
any(is_auth_code)
|
|
417
|
+
' >/dev/null 2>&1; then
|
|
418
|
+
echo "MCP_AUTH_ERROR"
|
|
419
|
+
return
|
|
420
|
+
fi
|
|
421
|
+
|
|
422
|
+
# whoami 的 logged_in=false 是正常登录入口事实,不能全局当作错误;仅已认证
|
|
423
|
+
# CLI/MCP 资源动作返回顶层或 data.logged_in=false 时提升为认证失效。
|
|
424
|
+
if [ "$ERROR_CONTEXT" = "MCP_AUTHENTICATED_CALL" ] &&
|
|
425
|
+
echo "$UNWRAPPED" | jq -e '
|
|
426
|
+
(type == "object") and (
|
|
427
|
+
((.logged_in? | type) == "boolean" and .logged_in == false) or
|
|
428
|
+
((.data? | type) == "object" and
|
|
429
|
+
(.data.logged_in? | type) == "boolean" and .data.logged_in == false)
|
|
430
|
+
)
|
|
431
|
+
' >/dev/null 2>&1; then
|
|
345
432
|
echo "MCP_AUTH_ERROR"
|
|
346
433
|
return
|
|
347
434
|
fi
|
|
@@ -647,10 +734,12 @@ handle_service_unstable() {
|
|
|
647
734
|
|
|
648
735
|
# ─── 统一错误处理入口 ──────────────────────────────────────────────────────
|
|
649
736
|
# 参数: $1 - CLI 执行结果文本(原始输出,含信封或不含)
|
|
737
|
+
# $2 - 可选调用上下文,透传给 detect_error
|
|
650
738
|
# 返回: 0=成功, 1=当前动作失败(由主流程判断恢复、阻断或继续独立分支)
|
|
651
739
|
handle_error() {
|
|
652
740
|
local CLI_RESULT="$1"
|
|
653
|
-
local
|
|
741
|
+
local ERROR_CONTEXT="${2:-}"
|
|
742
|
+
local ERROR_TYPE=$(detect_error "$CLI_RESULT" "$ERROR_CONTEXT")
|
|
654
743
|
# 解包一次供 CLI_ERROR 分支使用(其他分支由各自的 handler 自己解包)
|
|
655
744
|
local _UNWRAPPED=$(unwrap_mcp "$CLI_RESULT")
|
|
656
745
|
|
|
@@ -107,7 +107,7 @@ fetch_service_page() {
|
|
|
107
107
|
return 1
|
|
108
108
|
fi
|
|
109
109
|
|
|
110
|
-
if ! handle_error "$RESULT"; then
|
|
110
|
+
if ! handle_error "$RESULT" "MCP_AUTHENTICATED_CALL"; then
|
|
111
111
|
return 1
|
|
112
112
|
fi
|
|
113
113
|
|
|
@@ -385,7 +385,7 @@ service_save() {
|
|
|
385
385
|
fi
|
|
386
386
|
|
|
387
387
|
# 错误检测
|
|
388
|
-
if ! handle_error "$RESULT"; then
|
|
388
|
+
if ! handle_error "$RESULT" "MCP_AUTHENTICATED_CALL"; then
|
|
389
389
|
emit_control "SERVICE_SAVE_RESULT=FAILED"
|
|
390
390
|
exit 1
|
|
391
391
|
fi
|
|
@@ -84,7 +84,7 @@ wait
|
|
|
84
84
|
# 解析图片引用值(兼容 file upload 返回 fileKey 或 URL 字段)
|
|
85
85
|
parse_image_ref() {
|
|
86
86
|
local RAW=$(cat "$1")
|
|
87
|
-
if [ "$(detect_error "$RAW")" != "SUCCESS" ]; then
|
|
87
|
+
if [ "$(detect_error "$RAW" "MCP_AUTHENTICATED_CALL")" != "SUCCESS" ]; then
|
|
88
88
|
return 1
|
|
89
89
|
fi
|
|
90
90
|
# alipay-cli file upload 可能返回 MCP 信封,先解包
|
|
@@ -122,11 +122,11 @@ PAY_REF=$(parse_image_ref "$TMP_PAY")
|
|
|
122
122
|
check_upload_error() {
|
|
123
123
|
local RAW=$(cat "$1")
|
|
124
124
|
local ERROR_TYPE
|
|
125
|
-
ERROR_TYPE=$(detect_error "$RAW")
|
|
125
|
+
ERROR_TYPE=$(detect_error "$RAW" "MCP_AUTHENTICATED_CALL")
|
|
126
126
|
if [ "$ERROR_TYPE" = "MCP_AUTH_ERROR" ] && [ "${UPLOAD_AUTH_ERROR_SEEN:-false}" = "true" ]; then
|
|
127
127
|
return 1
|
|
128
128
|
fi
|
|
129
|
-
if ! handle_error "$RAW"; then
|
|
129
|
+
if ! handle_error "$RAW" "MCP_AUTHENTICATED_CALL"; then
|
|
130
130
|
if [ "$ERROR_TYPE" = "MCP_AUTH_ERROR" ]; then
|
|
131
131
|
UPLOAD_AUTH_ERROR_SEEN=true
|
|
132
132
|
fi
|