@itpay/cli 0.2.16 → 2.0.0-rc.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 +148 -447
- package/bin/itp +1 -150
- package/dist/src/client/backend.js +154 -0
- package/dist/src/client/http.js +76 -0
- package/dist/src/client/types.js +4 -0
- package/dist/src/commands/buy.js +351 -0
- package/dist/src/commands/cart.js +264 -0
- package/dist/src/commands/catalog.js +26 -0
- package/dist/src/commands/checkout.js +106 -0
- package/dist/src/commands/docs.js +61 -0
- package/dist/src/commands/guidance.js +422 -0
- package/dist/src/commands/install.js +95 -0
- package/dist/src/commands/order.js +78 -0
- package/dist/src/commands/orders.js +22 -0
- package/dist/src/commands/pay.js +26 -0
- package/dist/src/commands/readyz.js +8 -0
- package/dist/src/commands/refund.js +20 -0
- package/dist/src/commands/services.js +317 -0
- package/dist/src/main.js +606 -0
- package/dist/src/render/feishu.js +201 -0
- package/dist/src/render/ide.js +321 -0
- package/dist/src/render/index.js +57 -0
- package/dist/src/render/interaction.js +49 -0
- package/dist/src/render/markdown.js +83 -0
- package/dist/src/render/output.js +42 -0
- package/dist/src/render/plain_chat.js +60 -0
- package/dist/src/render/plan.js +31 -0
- package/dist/src/render/qr.js +32 -0
- package/dist/src/render/sink.js +6 -0
- package/dist/src/render/status.js +37 -0
- package/dist/src/render/telegram.js +172 -0
- package/dist/src/render/terminal.js +148 -0
- package/dist/src/render/terminal_image.js +19 -0
- package/dist/src/state/cart_session.js +151 -0
- package/dist/src/state/client_context.js +73 -0
- package/dist/src/state/config.js +82 -0
- package/dist/src/state/device_authority.js +217 -0
- package/dist/src/state/operation_journal.js +80 -0
- package/docs/agent/buyer/cart-checkout.json +56 -94
- package/docs/agent/buyer/catalog-list.json +47 -0
- package/docs/agent/buyer/install-and-setup.json +82 -0
- package/docs/agent/buyer/orders-refunds.json +76 -0
- package/docs/agent/buyer/payment-flow.json +77 -0
- package/docs/agent/buyer/quickstart.json +143 -75
- package/docs/agent/buyer/render-hosts.json +79 -0
- package/package.json +32 -13
- package/skills/itpay-buyer/SKILL.md +107 -238
- package/docs/agent/buyer/account-portal.json +0 -81
- package/docs/agent/buyer/catalog-search.json +0 -106
- package/docs/agent/buyer/human-claim-ui.json +0 -77
- package/docs/agent/buyer/payment-qr.json +0 -97
- package/docs/agent/buyer/payment-wait.json +0 -84
- package/docs/agent/buyer/product-recommendation.json +0 -80
- package/docs/agent/buyer/qr-refresh.json +0 -67
- package/docs/agent/buyer/recovery.json +0 -85
- package/docs/agent/buyer/safety-policy.json +0 -70
- package/docs/agent/buyer/secure-delivery.json +0 -90
- package/docs/agent/buyer/vault-agent-read.json +0 -95
- package/install.ps1 +0 -65
- package/install.sh +0 -66
- package/lib/account-status.js +0 -157
- package/lib/buyer.js +0 -2332
- package/lib/client-context.js +0 -126
- package/lib/docs.js +0 -200
- package/lib/env.js +0 -723
- package/lib/http.js +0 -151
- package/lib/ops.js +0 -135
- package/lib/render-human.js +0 -718
- package/lib/runtime.js +0 -1456
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"schema_version": "itp.agent_doc.v1",
|
|
3
|
-
"role": "buyer",
|
|
4
|
-
"topic": "vault-agent-read",
|
|
5
|
-
"title": "Human-Approved Vault Agent Read",
|
|
6
|
-
"purpose": "Teach the agent how to read only the artifact fields that the human explicitly approved with Passkey.",
|
|
7
|
-
"when_to_use": [
|
|
8
|
-
"The human opened the ItPay account portal and selected one-key agent authorization.",
|
|
9
|
-
"The user asks whether the agent can now see a purchased report or selected fields.",
|
|
10
|
-
"A checkout/order has delivered a vault artifact and the human granted agent-readable access."
|
|
11
|
-
],
|
|
12
|
-
"required_state": {
|
|
13
|
-
"needs": [
|
|
14
|
-
"checkout_id or authenticated buyer account session",
|
|
15
|
-
"current agent device binding",
|
|
16
|
-
"order_id or checkout_id or vault_artifact_id"
|
|
17
|
-
],
|
|
18
|
-
"must_not_need": [
|
|
19
|
-
"human portal token",
|
|
20
|
-
"claim token",
|
|
21
|
-
"passkey credential",
|
|
22
|
-
"raw protected payload",
|
|
23
|
-
"grant id copied by the human"
|
|
24
|
-
]
|
|
25
|
-
},
|
|
26
|
-
"commands": [
|
|
27
|
-
{
|
|
28
|
-
"intent": "check whether this agent has active human-approved grants for a checkout",
|
|
29
|
-
"command": "itp buyer vault grants list --checkout <checkout_id> --host <client> --json",
|
|
30
|
-
"success_signal": "response.agent_readable_grants is an array; count > 0 means the human has granted this exact agent access"
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
"intent": "check whether this agent has active human-approved grants for one order or artifact",
|
|
34
|
-
"command": "itp buyer vault grants list --order <order_id> --artifact <vault_artifact_id> --host <client> --json",
|
|
35
|
-
"success_signal": "only grants scoped to this logged-in agent device are returned"
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
"intent": "read a discovered grant view",
|
|
39
|
-
"command": "itp buyer vault grants read <agent_read_grant_id> --host <client> --json",
|
|
40
|
-
"success_signal": "response.grant contains selected_fields, structured_view, or summary according to the human-approved scope"
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
"intent": "convenience read by order/artifact without asking the human for grant id",
|
|
44
|
-
"command": "itp buyer vault read --order <order_id> --artifact <vault_artifact_id> --host <client> --json",
|
|
45
|
-
"success_signal": "the CLI discovers the active grant and reads its scoped view"
|
|
46
|
-
}
|
|
47
|
-
],
|
|
48
|
-
"agent_rules": [
|
|
49
|
-
"Only read through `buyer vault` commands after the human has explicitly approved the agent grant in the ItPay portal.",
|
|
50
|
-
"Prefer `itp buyer vault grants list --checkout <checkout_id> --host <client> --json`; the CLI can automatically restore the buyer agent session from the checkout auth handoff when possible.",
|
|
51
|
-
"If the response includes buyer_session.status=buyer_session_saved, continue directly to `buyer vault grants read <agent_read_grant_id> --host <client> --json`; do not ask the human for session tokens, auth IDs, or grant IDs.",
|
|
52
|
-
"Do not ask the human to copy or paste `agent_read_grant_id`; discover it with `buyer vault grants list`.",
|
|
53
|
-
"If no grant is returned, tell the human to open their ItPay account portal, reveal with Passkey, choose fields, and confirm one-key agent authorization.",
|
|
54
|
-
"If no grant is returned, explain likely causes: the human has not authorized yet, selected the wrong order/page, authorization has not synced yet, checkout/order/artifact does not match, buyer session expired, or the grant expired/revoked.",
|
|
55
|
-
"When no grant is returned, retry the same checkout/order after a short wait before asking for reauthorization. Do not ask the human to copy grant ids or tokens.",
|
|
56
|
-
"Use only fields returned in the grant view. Do not infer that unreturned fields are accessible.",
|
|
57
|
-
"When a grant view is returned, tell the user which fields are readable. If expires_at, ttl, or valid_until is present, tell the user the time limit; if no expiry is returned, say the response did not include an explicit expiry.",
|
|
58
|
-
"If the returned fields are not enough for the user's task, ask the human to reopen Give to Agent and add the needed fields. Do not ask them to paste the missing raw content.",
|
|
59
|
-
"If the command still returns 401 or buyer_session_invalid after using `--checkout`, run `itp buyer checkout status <checkout_id> --host <client> --json`, then retry `itp buyer vault grants list --checkout <checkout_id> --host <client> --json`. Ask the human to reauthorize only if the checkout/auth handoff has expired."
|
|
60
|
-
],
|
|
61
|
-
"forbidden": [
|
|
62
|
-
"Do not open, click through, scrape, or automate the human web UI yourself.",
|
|
63
|
-
"Do not open, scrape, or screenshot the human portal to obtain protected content.",
|
|
64
|
-
"Do not request passkey credentials, portal tokens, claim links, claim tokens, auth session IDs, display tokens, session tokens, storage refs, provider AppCode, provider keys, or raw payloads.",
|
|
65
|
-
"Do not use another agent's grant id. Grants are scoped to the exact buyer account session and agent device.",
|
|
66
|
-
"Do not cache selected fields beyond the task context unless the user explicitly asks you to create a local artifact."
|
|
67
|
-
],
|
|
68
|
-
"next_docs": [
|
|
69
|
-
{
|
|
70
|
-
"condition": "The human needs a portal link to grant access",
|
|
71
|
-
"topic": "account-portal",
|
|
72
|
-
"command": "itp docs show account-portal --role buyer --json"
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
"condition": "The order was delivered but no grant exists",
|
|
76
|
-
"topic": "secure-delivery",
|
|
77
|
-
"command": "itp docs show secure-delivery --role buyer --json"
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
"condition": "The agent is unsure what it may read",
|
|
81
|
-
"topic": "safety-policy",
|
|
82
|
-
"command": "itp docs show safety-policy --role buyer --json"
|
|
83
|
-
}
|
|
84
|
-
],
|
|
85
|
-
"search_terms": [
|
|
86
|
-
"vault",
|
|
87
|
-
"agent read",
|
|
88
|
-
"passkey grant",
|
|
89
|
-
"one key agent",
|
|
90
|
-
"授权给 agent",
|
|
91
|
-
"可读授权",
|
|
92
|
-
"字段授权",
|
|
93
|
-
"查看报告"
|
|
94
|
-
]
|
|
95
|
-
}
|
package/install.ps1
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
$ErrorActionPreference = "Stop"
|
|
2
|
-
|
|
3
|
-
$SourceDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
4
|
-
$ItpBin = Join-Path $SourceDir "bin\itp"
|
|
5
|
-
$LibDir = Join-Path $SourceDir "lib"
|
|
6
|
-
$SkillsDir = Join-Path $SourceDir "skills"
|
|
7
|
-
$DocsDir = Join-Path $SourceDir "docs"
|
|
8
|
-
$NodeModules = Join-Path $SourceDir "node_modules"
|
|
9
|
-
$PackageFile = Join-Path $SourceDir "package.json"
|
|
10
|
-
$Prefix = if ($env:ITP_PREFIX) { $env:ITP_PREFIX } else { Join-Path $HOME ".local" }
|
|
11
|
-
$TargetDir = Join-Path $Prefix "bin"
|
|
12
|
-
$TargetScript = Join-Path $TargetDir "itp.js"
|
|
13
|
-
$TargetCmd = Join-Path $TargetDir "itp.cmd"
|
|
14
|
-
$LibTarget = Join-Path $Prefix "lib"
|
|
15
|
-
$ModuleTarget = Join-Path $Prefix "node_modules"
|
|
16
|
-
$ShareTargetDir = Join-Path $Prefix "share\itpay_cli"
|
|
17
|
-
$SkillsTarget = Join-Path $ShareTargetDir "skills"
|
|
18
|
-
$DocsTarget = Join-Path $ShareTargetDir "docs"
|
|
19
|
-
$PackageTarget = Join-Path $ShareTargetDir "package.json"
|
|
20
|
-
|
|
21
|
-
if (!(Test-Path $ItpBin)) {
|
|
22
|
-
throw "itp binary not found at $ItpBin"
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
New-Item -ItemType Directory -Force -Path $TargetDir | Out-Null
|
|
26
|
-
Copy-Item -Force $ItpBin $TargetScript
|
|
27
|
-
if (Test-Path $LibDir) {
|
|
28
|
-
if (Test-Path $LibTarget) {
|
|
29
|
-
Remove-Item -Recurse -Force $LibTarget
|
|
30
|
-
}
|
|
31
|
-
Copy-Item -Recurse -Force $LibDir $LibTarget
|
|
32
|
-
}
|
|
33
|
-
if (Test-Path $NodeModules) {
|
|
34
|
-
if (Test-Path $ModuleTarget) {
|
|
35
|
-
Remove-Item -Recurse -Force $ModuleTarget
|
|
36
|
-
}
|
|
37
|
-
Copy-Item -Recurse -Force $NodeModules $ModuleTarget
|
|
38
|
-
}
|
|
39
|
-
New-Item -ItemType Directory -Force -Path $ShareTargetDir | Out-Null
|
|
40
|
-
if (Test-Path $PackageFile) {
|
|
41
|
-
Copy-Item -Force $PackageFile $PackageTarget
|
|
42
|
-
}
|
|
43
|
-
if (Test-Path $SkillsDir) {
|
|
44
|
-
if (Test-Path $SkillsTarget) {
|
|
45
|
-
Remove-Item -Recurse -Force $SkillsTarget
|
|
46
|
-
}
|
|
47
|
-
Copy-Item -Recurse -Force $SkillsDir $SkillsTarget
|
|
48
|
-
}
|
|
49
|
-
if (Test-Path $DocsDir) {
|
|
50
|
-
if (Test-Path $DocsTarget) {
|
|
51
|
-
Remove-Item -Recurse -Force $DocsTarget
|
|
52
|
-
}
|
|
53
|
-
Copy-Item -Recurse -Force $DocsDir $DocsTarget
|
|
54
|
-
}
|
|
55
|
-
Set-Content -Path $TargetCmd -Encoding ASCII -Value @"
|
|
56
|
-
@echo off
|
|
57
|
-
node "%~dp0itp.js" %*
|
|
58
|
-
"@
|
|
59
|
-
|
|
60
|
-
Write-Output "Installed itp to $TargetCmd"
|
|
61
|
-
if (($env:Path -split ';') -notcontains $TargetDir) {
|
|
62
|
-
Write-Output "Add $TargetDir to PATH before running itp."
|
|
63
|
-
} else {
|
|
64
|
-
& $TargetCmd --version
|
|
65
|
-
}
|
package/install.sh
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env sh
|
|
2
|
-
set -eu
|
|
3
|
-
|
|
4
|
-
SOURCE_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
|
5
|
-
ITP_BIN="$SOURCE_DIR/bin/itp"
|
|
6
|
-
LIB_DIR="$SOURCE_DIR/lib"
|
|
7
|
-
SKILLS_DIR="$SOURCE_DIR/skills"
|
|
8
|
-
DOCS_DIR="$SOURCE_DIR/docs"
|
|
9
|
-
NODE_MODULES="$SOURCE_DIR/node_modules"
|
|
10
|
-
PREFIX="${ITP_PREFIX:-$HOME/.local}"
|
|
11
|
-
TARGET_DIR="$PREFIX/bin"
|
|
12
|
-
TARGET="$TARGET_DIR/itp"
|
|
13
|
-
SHARE_TARGET_DIR="$PREFIX/share/itpay_cli"
|
|
14
|
-
LIB_TARGET="$PREFIX/lib"
|
|
15
|
-
MODULE_TARGET="$PREFIX/node_modules"
|
|
16
|
-
PACKAGE_FILE="$SOURCE_DIR/package.json"
|
|
17
|
-
|
|
18
|
-
if [ ! -f "$ITP_BIN" ]; then
|
|
19
|
-
echo "itp binary not found at $ITP_BIN" >&2
|
|
20
|
-
exit 1
|
|
21
|
-
fi
|
|
22
|
-
|
|
23
|
-
mkdir -p "$TARGET_DIR"
|
|
24
|
-
chmod +x "$ITP_BIN"
|
|
25
|
-
cp "$ITP_BIN" "$TARGET"
|
|
26
|
-
chmod +x "$TARGET"
|
|
27
|
-
|
|
28
|
-
if [ -d "$LIB_DIR" ]; then
|
|
29
|
-
rm -rf "$LIB_TARGET"
|
|
30
|
-
cp -R "$LIB_DIR" "$LIB_TARGET"
|
|
31
|
-
find "$LIB_TARGET" -type f -exec chmod 0644 {} \;
|
|
32
|
-
fi
|
|
33
|
-
|
|
34
|
-
if [ -d "$NODE_MODULES" ]; then
|
|
35
|
-
rm -rf "$MODULE_TARGET"
|
|
36
|
-
cp -R "$NODE_MODULES" "$MODULE_TARGET"
|
|
37
|
-
fi
|
|
38
|
-
|
|
39
|
-
mkdir -p "$SHARE_TARGET_DIR"
|
|
40
|
-
if [ -f "$PACKAGE_FILE" ]; then
|
|
41
|
-
cp "$PACKAGE_FILE" "$SHARE_TARGET_DIR/package.json"
|
|
42
|
-
chmod 0644 "$SHARE_TARGET_DIR/package.json"
|
|
43
|
-
fi
|
|
44
|
-
|
|
45
|
-
if [ -d "$SKILLS_DIR" ]; then
|
|
46
|
-
rm -rf "$SHARE_TARGET_DIR/skills"
|
|
47
|
-
cp -R "$SKILLS_DIR" "$SHARE_TARGET_DIR/skills"
|
|
48
|
-
find "$SHARE_TARGET_DIR/skills" -type f -exec chmod 0644 {} \;
|
|
49
|
-
fi
|
|
50
|
-
|
|
51
|
-
if [ -d "$DOCS_DIR" ]; then
|
|
52
|
-
rm -rf "$SHARE_TARGET_DIR/docs"
|
|
53
|
-
cp -R "$DOCS_DIR" "$SHARE_TARGET_DIR/docs"
|
|
54
|
-
find "$SHARE_TARGET_DIR/docs" -type f -exec chmod 0644 {} \;
|
|
55
|
-
fi
|
|
56
|
-
|
|
57
|
-
case ":$PATH:" in
|
|
58
|
-
*":$TARGET_DIR:"*) ;;
|
|
59
|
-
*)
|
|
60
|
-
echo "Installed itp to $TARGET"
|
|
61
|
-
echo "Add $TARGET_DIR to PATH before running itp."
|
|
62
|
-
exit 0
|
|
63
|
-
;;
|
|
64
|
-
esac
|
|
65
|
-
|
|
66
|
-
"$TARGET" --version
|
package/lib/account-status.js
DELETED
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
import { coreApi } from "./http.js";
|
|
2
|
-
import { noRecoverableContext } from "./buyer.js";
|
|
3
|
-
import { cliCommand, output, readConfig, readCredentials, readSessionToken, safeErrorMessage } from "./env.js";
|
|
4
|
-
|
|
5
|
-
async function accountOverviewStatus(flags = {}) {
|
|
6
|
-
const config = readConfig();
|
|
7
|
-
const credentials = readCredentials();
|
|
8
|
-
const hasLocalSession = Boolean(readSessionToken(credentials) || flags.access_token);
|
|
9
|
-
const base = {
|
|
10
|
-
schema_version: "itp.agent.v1",
|
|
11
|
-
status: hasLocalSession ? "account_status_unavailable" : "unauthenticated",
|
|
12
|
-
phase: hasLocalSession ? "account_status_unavailable" : "unauthenticated",
|
|
13
|
-
authenticated: false,
|
|
14
|
-
session_verified: !hasLocalSession,
|
|
15
|
-
auth_source: hasLocalSession ? "local_files_unverified" : "local_files",
|
|
16
|
-
account_id: config.account_id || null,
|
|
17
|
-
buyer_account_id: config.account_id || null,
|
|
18
|
-
device_id: config.device_id || null,
|
|
19
|
-
agent_device_id: config.device_id || null,
|
|
20
|
-
linked_providers: [],
|
|
21
|
-
order_count: 0,
|
|
22
|
-
created_at: null,
|
|
23
|
-
device: config.device_id ? { agent_device_id: config.device_id } : null,
|
|
24
|
-
next: hasLocalSession
|
|
25
|
-
? { type: "retry_status", command: cliCommand("status", "--json"), safe_for_agent: true }
|
|
26
|
-
: { type: "start_auth", command: cliCommand("setup", "--plan", "credit-300", "--method", "alipay", "--json"), safe_for_agent: true },
|
|
27
|
-
recoverable_context: noRecoverableContext(),
|
|
28
|
-
agent_next_actions: hasLocalSession
|
|
29
|
-
? ["run_status_refresh", "view_orders", "create_refund_if_needed", "list_agent_read_grants"]
|
|
30
|
-
: ["start_human_auth_if_unauthenticated"],
|
|
31
|
-
secrets: { raw_key_included: false, session_token_included: false }
|
|
32
|
-
};
|
|
33
|
-
if (!hasLocalSession) return base;
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
const me = await coreApi("/v1/me", { method: "GET" }, flags);
|
|
37
|
-
const authenticated = Boolean(me.authenticated);
|
|
38
|
-
const accountID = me.buyer_account_id || config.account_id || null;
|
|
39
|
-
const deviceID = me.agent_device_id || me.device?.agent_device_id || config.device_id || null;
|
|
40
|
-
return {
|
|
41
|
-
...base,
|
|
42
|
-
status: authenticated ? "idle" : "unauthenticated",
|
|
43
|
-
phase: authenticated ? "idle" : "unauthenticated",
|
|
44
|
-
authenticated,
|
|
45
|
-
session_verified: true,
|
|
46
|
-
auth_source: "core",
|
|
47
|
-
account_id: accountID,
|
|
48
|
-
buyer_account_id: accountID,
|
|
49
|
-
device_id: deviceID,
|
|
50
|
-
agent_device_id: deviceID,
|
|
51
|
-
linked_providers: Array.isArray(me.linked_providers) ? me.linked_providers : [],
|
|
52
|
-
order_count: Number.isFinite(Number(me.order_count)) ? Number(me.order_count) : 0,
|
|
53
|
-
created_at: me.created_at || null,
|
|
54
|
-
device: me.device || (deviceID ? { agent_device_id: deviceID } : null),
|
|
55
|
-
next: authenticated
|
|
56
|
-
? { type: "buyer_ready", command: cliCommand("buyer", "auth", "status", "--json"), safe_for_agent: true }
|
|
57
|
-
: base.next,
|
|
58
|
-
agent_next_actions: authenticated
|
|
59
|
-
? ["search_catalog", "view_orders", "create_refund_if_needed", "list_agent_read_grants"]
|
|
60
|
-
: ["start_human_auth_if_unauthenticated"],
|
|
61
|
-
backend: {
|
|
62
|
-
environment: me.environment || null,
|
|
63
|
-
backend_version: me.backend_version || null
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
} catch (error) {
|
|
67
|
-
return {
|
|
68
|
-
...base,
|
|
69
|
-
error: safeErrorMessage(error)
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function outputAccountStatus(status, flags = {}) {
|
|
75
|
-
if (flags.json) {
|
|
76
|
-
output(status);
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
console.log(formatStatusText(status));
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function formatStatusText(status = {}) {
|
|
83
|
-
if (!status.authenticated) {
|
|
84
|
-
const lines = [
|
|
85
|
-
`Account: ${status.account_id ? `${status.account_id} (unverified)` : "not signed in"}`,
|
|
86
|
-
"Linked: -",
|
|
87
|
-
"Orders: -",
|
|
88
|
-
`Device: ${formatDeviceLine(status.device, status.device_id) || "-"}`
|
|
89
|
-
];
|
|
90
|
-
if (status.error) lines.push(`Error: ${status.error}`);
|
|
91
|
-
return lines.join("\n");
|
|
92
|
-
}
|
|
93
|
-
const linked = Array.isArray(status.linked_providers) && status.linked_providers.length
|
|
94
|
-
? status.linked_providers.join(", ")
|
|
95
|
-
: "-";
|
|
96
|
-
return [
|
|
97
|
-
`Account: ${status.buyer_account_id || status.account_id || "-"}`,
|
|
98
|
-
`Linked: ${linked}`,
|
|
99
|
-
`Orders: ${Number.isFinite(Number(status.order_count)) ? Number(status.order_count) : 0}`,
|
|
100
|
-
`Device: ${formatDeviceLine(status.device, status.device_id) || "-"}`
|
|
101
|
-
].join("\n");
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function formatDeviceLine(device, fallbackID = "") {
|
|
105
|
-
const displayName = String(device?.display_name || "").trim();
|
|
106
|
-
const deviceID = String(device?.agent_device_id || fallbackID || "").trim();
|
|
107
|
-
const label = displayName || deviceID;
|
|
108
|
-
if (!label) return "";
|
|
109
|
-
const status = String(device?.status || "").trim();
|
|
110
|
-
return status ? `${label} (${status})` : label;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
async function refreshBuyerSessionForStatus(flags = {}) {
|
|
114
|
-
const config = readConfig();
|
|
115
|
-
const credentials = readCredentials();
|
|
116
|
-
if (!readSessionToken(credentials)) {
|
|
117
|
-
return {
|
|
118
|
-
authenticated: false,
|
|
119
|
-
session_verified: true,
|
|
120
|
-
account_id: config.account_id || null,
|
|
121
|
-
device_id: config.device_id || null,
|
|
122
|
-
auth_source: "core_no_session"
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
try {
|
|
126
|
-
const status = await coreApi("/v1/me/auth/status", { method: "GET" }, flags);
|
|
127
|
-
return {
|
|
128
|
-
authenticated: true,
|
|
129
|
-
session_verified: true,
|
|
130
|
-
account_id: status.buyer_account_id || config.account_id || null,
|
|
131
|
-
device_id: config.device_id || null,
|
|
132
|
-
account_status: status.account_status || null,
|
|
133
|
-
auth_source: "core"
|
|
134
|
-
};
|
|
135
|
-
} catch (error) {
|
|
136
|
-
return {
|
|
137
|
-
authenticated: false,
|
|
138
|
-
session_verified: true,
|
|
139
|
-
account_id: config.account_id || null,
|
|
140
|
-
device_id: config.device_id || null,
|
|
141
|
-
auth_source: "core",
|
|
142
|
-
error: safeErrorMessage(error)
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
function nextActionForAuthStatus(auth = {}, flags = {}) {
|
|
148
|
-
if (auth.authenticated && auth.session_verified === false) {
|
|
149
|
-
return { type: "verify_buyer_session", command: cliCommand("status", "--refresh", "--json"), safe_for_agent: true };
|
|
150
|
-
}
|
|
151
|
-
if (auth.authenticated) {
|
|
152
|
-
return { type: "buyer_ready", command: cliCommand("buyer", "auth", "status", "--json"), safe_for_agent: true };
|
|
153
|
-
}
|
|
154
|
-
return { type: "start_auth", command: cliCommand("setup", "--plan", "credit-300", "--method", "alipay", "--json"), safe_for_agent: true };
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
export { accountOverviewStatus, outputAccountStatus, refreshBuyerSessionForStatus, nextActionForAuthStatus };
|