@itpay/cli 0.2.17 → 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.
Files changed (69) hide show
  1. package/README.md +148 -447
  2. package/bin/itp +1 -150
  3. package/dist/src/client/backend.js +154 -0
  4. package/dist/src/client/http.js +76 -0
  5. package/dist/src/client/types.js +4 -0
  6. package/dist/src/commands/buy.js +351 -0
  7. package/dist/src/commands/cart.js +264 -0
  8. package/dist/src/commands/catalog.js +26 -0
  9. package/dist/src/commands/checkout.js +106 -0
  10. package/dist/src/commands/docs.js +61 -0
  11. package/dist/src/commands/guidance.js +422 -0
  12. package/dist/src/commands/install.js +95 -0
  13. package/dist/src/commands/order.js +78 -0
  14. package/dist/src/commands/orders.js +22 -0
  15. package/dist/src/commands/pay.js +26 -0
  16. package/dist/src/commands/readyz.js +8 -0
  17. package/dist/src/commands/refund.js +20 -0
  18. package/dist/src/commands/services.js +317 -0
  19. package/dist/src/main.js +606 -0
  20. package/dist/src/render/feishu.js +201 -0
  21. package/dist/src/render/ide.js +321 -0
  22. package/dist/src/render/index.js +57 -0
  23. package/dist/src/render/interaction.js +49 -0
  24. package/dist/src/render/markdown.js +83 -0
  25. package/dist/src/render/output.js +42 -0
  26. package/dist/src/render/plain_chat.js +60 -0
  27. package/dist/src/render/plan.js +31 -0
  28. package/dist/src/render/qr.js +32 -0
  29. package/dist/src/render/sink.js +6 -0
  30. package/dist/src/render/status.js +37 -0
  31. package/dist/src/render/telegram.js +172 -0
  32. package/dist/src/render/terminal.js +148 -0
  33. package/dist/src/render/terminal_image.js +19 -0
  34. package/dist/src/state/cart_session.js +151 -0
  35. package/dist/src/state/client_context.js +73 -0
  36. package/dist/src/state/config.js +82 -0
  37. package/dist/src/state/device_authority.js +217 -0
  38. package/dist/src/state/operation_journal.js +80 -0
  39. package/docs/agent/buyer/cart-checkout.json +56 -94
  40. package/docs/agent/buyer/catalog-list.json +47 -0
  41. package/docs/agent/buyer/install-and-setup.json +82 -0
  42. package/docs/agent/buyer/orders-refunds.json +76 -0
  43. package/docs/agent/buyer/payment-flow.json +77 -0
  44. package/docs/agent/buyer/quickstart.json +143 -75
  45. package/docs/agent/buyer/render-hosts.json +79 -0
  46. package/package.json +32 -13
  47. package/skills/itpay-buyer/SKILL.md +107 -238
  48. package/docs/agent/buyer/account-portal.json +0 -81
  49. package/docs/agent/buyer/catalog-search.json +0 -106
  50. package/docs/agent/buyer/human-claim-ui.json +0 -77
  51. package/docs/agent/buyer/payment-qr.json +0 -97
  52. package/docs/agent/buyer/payment-wait.json +0 -84
  53. package/docs/agent/buyer/product-recommendation.json +0 -80
  54. package/docs/agent/buyer/qr-refresh.json +0 -67
  55. package/docs/agent/buyer/recovery.json +0 -85
  56. package/docs/agent/buyer/safety-policy.json +0 -70
  57. package/docs/agent/buyer/secure-delivery.json +0 -90
  58. package/docs/agent/buyer/vault-agent-read.json +0 -95
  59. package/install.ps1 +0 -65
  60. package/install.sh +0 -66
  61. package/lib/account-status.js +0 -157
  62. package/lib/buyer.js +0 -2332
  63. package/lib/client-context.js +0 -126
  64. package/lib/docs.js +0 -200
  65. package/lib/env.js +0 -723
  66. package/lib/http.js +0 -151
  67. package/lib/ops.js +0 -135
  68. package/lib/render-human.js +0 -718
  69. 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
@@ -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 };