@itpay/cli 2.0.7 → 2.0.9
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
CHANGED
|
@@ -11,7 +11,7 @@ itpay --agent-type codex-desktop readyz --json
|
|
|
11
11
|
# follow next.command: typed skill show, then catalog list
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
The default API is `https://
|
|
14
|
+
The default API is temporarily `https://dev.itpay.ai` during the 2.0.9 beta. Set `ITPAY_BACKEND_URL` only for an intentional override.
|
|
15
15
|
|
|
16
16
|
## Output Contract
|
|
17
17
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { HttpError } from "../client/http.js";
|
|
2
|
+
import { API_CONTRACT_REVISION, CLI_VERSION } from "../state/config.js";
|
|
3
|
+
export async function requirePlatformCompatibility(backend) {
|
|
4
|
+
const platform = await backend.compatibility();
|
|
5
|
+
const compatible = platform.api_contract_revision === API_CONTRACT_REVISION
|
|
6
|
+
&& compareVersions(CLI_VERSION, platform.minimum_cli_version) >= 0
|
|
7
|
+
&& versionMajor(CLI_VERSION) <= platform.maximum_cli_major;
|
|
8
|
+
if (compatible)
|
|
9
|
+
return;
|
|
10
|
+
throw new HttpError(426, {
|
|
11
|
+
code: "client_upgrade_required",
|
|
12
|
+
message: `CLI ${CLI_VERSION} contract ${API_CONTRACT_REVISION} is incompatible with platform ${platform.platform_revision} contract ${platform.api_contract_revision} (minimum CLI ${platform.minimum_cli_version}, maximum major ${platform.maximum_cli_major})`,
|
|
13
|
+
}, "CLI is incompatible with the active ItPay platform release");
|
|
14
|
+
}
|
|
15
|
+
function compareVersions(left, right) {
|
|
16
|
+
const a = versionParts(left);
|
|
17
|
+
const b = versionParts(right);
|
|
18
|
+
if (!a || !b)
|
|
19
|
+
return -1;
|
|
20
|
+
for (let index = 0; index < 3; index += 1) {
|
|
21
|
+
if (a[index] !== b[index])
|
|
22
|
+
return a[index] - b[index];
|
|
23
|
+
}
|
|
24
|
+
return 0;
|
|
25
|
+
}
|
|
26
|
+
function versionMajor(version) {
|
|
27
|
+
return versionParts(version)?.[0] ?? Number.MAX_SAFE_INTEGER;
|
|
28
|
+
}
|
|
29
|
+
function versionParts(version) {
|
|
30
|
+
const match = /^(\d+)\.(\d+)\.(\d+)$/.exec(version.trim());
|
|
31
|
+
return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : undefined;
|
|
32
|
+
}
|
package/dist/src/main.js
CHANGED
|
@@ -10,6 +10,7 @@ import { HttpError } from "./client/http.js";
|
|
|
10
10
|
import { runReadyz } from "./commands/readyz.js";
|
|
11
11
|
import { runBuy } from "./commands/buy.js";
|
|
12
12
|
import { runCatalogList } from "./commands/catalog.js";
|
|
13
|
+
import { requirePlatformCompatibility } from "./commands/compatibility.js";
|
|
13
14
|
import { runCheckoutPresentation } from "./commands/checkout.js";
|
|
14
15
|
import { runPay } from "./commands/pay.js";
|
|
15
16
|
import { runOrder } from "./commands/order.js";
|
|
@@ -94,6 +95,7 @@ function reportCLIError(error, contract) {
|
|
|
94
95
|
error.code === "client_compatibility_headers_required" ||
|
|
95
96
|
error.code === "platform_release_unavailable" ||
|
|
96
97
|
(error.status === 404 && error.code === "unknown_error"));
|
|
98
|
+
const backendInternal = error instanceof HttpError && error.status === 500 && error.code === "internal_error";
|
|
97
99
|
const deviceRecovery = deviceError ? [{
|
|
98
100
|
command: "itpay skill show itpay-buyer --json",
|
|
99
101
|
reason: "读取身份边界;该错误需要用户或运营恢复 Backend 登记,不能通过换类型或删除本地身份绕过",
|
|
@@ -119,10 +121,12 @@ function reportCLIError(error, contract) {
|
|
|
119
121
|
message: error instanceof Error ? error.message : String(error),
|
|
120
122
|
},
|
|
121
123
|
instruction: incompatible
|
|
122
|
-
? "
|
|
123
|
-
:
|
|
124
|
+
? "立即向用户报告 error.message 并结束本次任务。不要运行任何其他 itpay、npm、which、device、docs、cart、orders 或 services 命令;不要寻找、安装或切换其他 CLI。只有运营明确提供兼容 CLI 后,才能在新的任务中重新开始。"
|
|
125
|
+
: backendInternal
|
|
126
|
+
? "Backend 内部故障;立即停止并向用户报告。不要重试、检查或删除 Device 身份、创建替代 Execution、切换 Backend,或尝试 quote、checkout、cart、buy、pay 等付费路径。"
|
|
127
|
+
: commandError?.instruction ?? authorizationInstruction ?? contract?.instruction ?? "检查命令参数后重试。",
|
|
124
128
|
next: null,
|
|
125
|
-
recovery: incompatible ? [] : commandError?.recovery ?? (stateError ? stateRecovery : deviceError ? deviceRecovery : identityRecovery ? httpRecovery : contract?.recovery ?? []),
|
|
129
|
+
recovery: incompatible || backendInternal ? [] : commandError?.recovery ?? (stateError ? stateRecovery : deviceError ? deviceRecovery : identityRecovery ? httpRecovery : contract?.recovery ?? []),
|
|
126
130
|
}, {
|
|
127
131
|
...(contract?.jsonOutput !== undefined ? { jsonOutput: contract.jsonOutput } : {}),
|
|
128
132
|
output: (text) => { process.stderr.write(text); },
|
|
@@ -159,6 +163,7 @@ program
|
|
|
159
163
|
const config = loadConfig();
|
|
160
164
|
const backend = newBackendClient(config);
|
|
161
165
|
try {
|
|
166
|
+
await requirePlatformCompatibility(backend);
|
|
162
167
|
await runReadyz(backend, { jsonOutput: Boolean(options.json), ...(config.agentType ? { agentType: config.agentType } : {}) });
|
|
163
168
|
}
|
|
164
169
|
catch (error) {
|
|
@@ -254,8 +259,19 @@ program
|
|
|
254
259
|
.option("--json", "output JSON instead of terminal text")
|
|
255
260
|
.action(async (options) => {
|
|
256
261
|
const config = loadConfig();
|
|
257
|
-
|
|
258
|
-
|
|
262
|
+
try {
|
|
263
|
+
await requirePlatformCompatibility(newBackendClient(config));
|
|
264
|
+
const session = CartSession.loadFromFile(cartSessionPath(), config.checkoutCurrency);
|
|
265
|
+
runNext(session, { jsonOutput: Boolean(options.json) });
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
reportCLIError(error, {
|
|
269
|
+
jsonOutput: Boolean(options.json),
|
|
270
|
+
code: "next_unavailable",
|
|
271
|
+
instruction: "Backend 合同可用后再读取本地恢复句柄;不要根据旧句柄继续交易。",
|
|
272
|
+
recovery: [],
|
|
273
|
+
});
|
|
274
|
+
}
|
|
259
275
|
});
|
|
260
276
|
// --- catalog --------------------------------------------------------------
|
|
261
277
|
const catalogCmd = program.command("catalog").description("Browse V3 service catalog");
|
|
@@ -266,6 +282,7 @@ catalogCmd
|
|
|
266
282
|
.action(async (options) => {
|
|
267
283
|
const backend = newBackendClient(loadConfig());
|
|
268
284
|
try {
|
|
285
|
+
await requirePlatformCompatibility(backend);
|
|
269
286
|
await runCatalogList(backend, { jsonOutput: Boolean(options.json) });
|
|
270
287
|
}
|
|
271
288
|
catch (error) {
|
package/dist/src/state/config.js
CHANGED
|
@@ -9,9 +9,9 @@ import { BackendClient } from "../client/backend.js";
|
|
|
9
9
|
import { declaredAgentType } from "./agent_type.js";
|
|
10
10
|
import { DeviceAuthority } from "./device_authority.js";
|
|
11
11
|
import { OperationJournal } from "./operation_journal.js";
|
|
12
|
-
export const DEFAULT_BASE_URL = "https://
|
|
13
|
-
export const CLI_VERSION = "2.0.
|
|
14
|
-
export const API_CONTRACT_REVISION = "sha256:
|
|
12
|
+
export const DEFAULT_BASE_URL = "https://dev.itpay.ai";
|
|
13
|
+
export const CLI_VERSION = "2.0.9";
|
|
14
|
+
export const API_CONTRACT_REVISION = "sha256:4ad3ff2565cc265a8c98dec3bb92be1cbfee4d37cb78756d929c78ef134a7bca";
|
|
15
15
|
const CART_SESSION_DEFAULT_DIR = ".itpay-v3";
|
|
16
16
|
const CART_SESSION_FILENAME = "cart.json";
|
|
17
17
|
const OPERATION_JOURNAL_FILENAME = "operations.json";
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
],
|
|
33
33
|
"agent_rules": [
|
|
34
34
|
"Install with npm install -g @itpay/cli.",
|
|
35
|
-
"Use the default https://
|
|
35
|
+
"Use the default https://dev.itpay.ai beta API unless an environment override is deliberate.",
|
|
36
36
|
"Use one exact type: codex-desktop, codex-cli, claude-code-desktop, claude-code-cli, or workbuddy.",
|
|
37
37
|
"One local private key is reused, but each exact Backend API base URL has its own server registration and quota lineage.",
|
|
38
38
|
"Within one Backend registration, each Agent Type has one Agent Instance; all windows and chats of the same type reuse it.",
|
|
@@ -29,7 +29,7 @@ itpay install [target] [--json]
|
|
|
29
29
|
"result": {
|
|
30
30
|
"agent_type": "codex-desktop",
|
|
31
31
|
"default_host": "codex",
|
|
32
|
-
"default_api": "https://
|
|
32
|
+
"default_api": "https://dev.itpay.ai",
|
|
33
33
|
"install_command": "npm install -g @itpay/cli"
|
|
34
34
|
},
|
|
35
35
|
"instruction": "在 Codex Desktop 中始终传这个 Agent Type;付款时把返回的二维码和链接实际展示到当前对话。",
|