@itpay/cli 2.0.14 → 2.0.15
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 +5 -4
- package/dist/src/commands/guidance.js +6 -5
- package/dist/src/commands/install.js +2 -2
- package/dist/src/commands/readyz.js +6 -2
- package/dist/src/main.js +18 -12
- package/dist/src/state/config.js +41 -7
- package/docs/agent/buyer/identity-and-sessions.json +10 -10
- package/docs/agent/buyer/install-and-setup.json +4 -5
- package/docs/agent/buyer/quickstart.json +3 -2
- package/docs/cli-reference/commands/cart/remove.md +1 -1
- package/docs/cli-reference/commands/device.md +1 -1
- package/docs/cli-reference/commands/install.md +2 -2
- package/docs/cli-reference/commands/readyz.md +35 -8
- package/docs/skill-bundle-rollout/01-mcp-authentication.md +256 -0
- package/docs/skill-bundle-rollout/02-platform-bundle-repositories.md +282 -0
- package/docs/skill-bundle-rollout/03-platform-publishing.md +270 -0
- package/docs/skill-bundle-rollout/README.md +98 -0
- package/package.json +1 -1
- package/skills/itpay/SKILL.md +3 -3
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ itpay --agent-type codex-desktop readyz --json
|
|
|
15
15
|
# follow next.command: typed skill show, then catalog list
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
The
|
|
18
|
+
The CLI defaults to the production Backend `https://app.itpay.ai`. Explicit tests may set `ITPAY_BACKEND_URL=https://dev.itpay.ai`; every other Backend URL is rejected before network or local state access.
|
|
19
19
|
|
|
20
20
|
## Output Contract
|
|
21
21
|
|
|
@@ -46,11 +46,11 @@ Normative per-command contracts: [CLI Command Reference](docs/cli-reference/inde
|
|
|
46
46
|
|
|
47
47
|
`--agent-type` identifies the stable runtime and registered Agent instance. Every returned ItPay command preserves it. Different windows or chats of the same type reuse one Agent Instance; they are not separate identities. `--host` only selects the human presentation surface, and `--target` only routes output to a Host destination. Use `itpay install <agent_type> --json` for the exact responsibility.
|
|
48
48
|
|
|
49
|
-
The local installation keeps one Ed25519 private key and
|
|
49
|
+
The local installation keeps one Ed25519 private key and a separate registration for each official Backend, with one Agent Instance per Agent Type under each registration. A rejected session is renewed and the same request is retried once; revoked v2 registrations are never silently replaced.
|
|
50
50
|
|
|
51
51
|
## Command Families
|
|
52
52
|
|
|
53
|
-
- `readyz`:
|
|
53
|
+
- `readyz`: selected official Backend liveness; `catalog list`: compatibility-gated discovery.
|
|
54
54
|
- `services start/invoke/action/checkout/next`: generic Service Execution flow.
|
|
55
55
|
- `cart add/show/remove/clear/next`, `buy`: canonical Cart and ordinary Checkout flow.
|
|
56
56
|
- `checkout`: authoritative payment and fulfillment recovery.
|
|
@@ -75,11 +75,12 @@ itpay --agent-type <agent_type> services checkout <service_execution_id> --resum
|
|
|
75
75
|
itpay checkout --id <checkout_id> --token <display_token> --json
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
The local `~/.itpay-v3` directory stores one owner-only signing key,
|
|
78
|
+
The local `~/.itpay-v3` directory stores one owner-only signing key, Backend-scoped Device registrations and Agent instances, idempotency operations, and recovery handles. Production uses `cart.json` / `operations.json`; dev uses `cart.dev.json` / `operations.dev.json`. Backend state remains authoritative. Do not delete or rotate this identity to recover quota.
|
|
79
79
|
|
|
80
80
|
## Environment
|
|
81
81
|
|
|
82
82
|
- `ITPAY_AGENT_TYPE`: stable alternative to global `--agent-type`.
|
|
83
|
+
- `ITPAY_BACKEND_URL`: optional test override; only the exact official URL `https://dev.itpay.ai` is accepted. Unset it for production.
|
|
83
84
|
- `ITPAY_BEARER_TOKEN`: account-scoped Buyer session for account-only commands such as `orders`.
|
|
84
85
|
- `ITPAY_CART_SESSION_PATH`: local recovery-state path override.
|
|
85
86
|
- `ITPAY_CURRENCY`: ordinary Cart currency, default `CNY`.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { HttpError } from "../client/http.js";
|
|
2
2
|
import { resolveOutput } from "../render/sink.js";
|
|
3
3
|
import { declaredAgentType, qualifyItPayCommand } from "../state/agent_type.js";
|
|
4
|
+
import { qualifyBackendCommand } from "../state/config.js";
|
|
4
5
|
export function isTerminalServiceExecutionStatus(status) {
|
|
5
6
|
return status === "failed" || status === "refunded" || status === "cancelled";
|
|
6
7
|
}
|
|
@@ -84,7 +85,7 @@ export function printAgentGuidance(guidance, output) {
|
|
|
84
85
|
out("next actions:\n");
|
|
85
86
|
for (const action of guidance.next_actions) {
|
|
86
87
|
out(` - ${action.label}\n`);
|
|
87
|
-
out(` ${qualifyItPayCommand(action.command, agentType)}\n`);
|
|
88
|
+
out(` ${qualifyBackendCommand(qualifyItPayCommand(action.command, agentType))}\n`);
|
|
88
89
|
if (action.requires_human)
|
|
89
90
|
out(" requires human confirmation\n");
|
|
90
91
|
if (action.reason)
|
|
@@ -95,17 +96,17 @@ export function printAgentGuidance(guidance, output) {
|
|
|
95
96
|
out("recovery:\n");
|
|
96
97
|
for (const action of guidance.recovery) {
|
|
97
98
|
out(` - ${action.label}\n`);
|
|
98
|
-
out(` ${qualifyItPayCommand(action.command, agentType)}\n`);
|
|
99
|
+
out(` ${qualifyBackendCommand(qualifyItPayCommand(action.command, agentType))}\n`);
|
|
99
100
|
}
|
|
100
101
|
}
|
|
101
102
|
}
|
|
102
103
|
function qualifyEnvelope(value, agentType) {
|
|
103
104
|
return {
|
|
104
105
|
...value,
|
|
105
|
-
next: value.next ? { ...value.next, command: qualifyItPayCommand(value.next.command, agentType) } : null,
|
|
106
|
+
next: value.next ? { ...value.next, command: qualifyBackendCommand(qualifyItPayCommand(value.next.command, agentType)) } : null,
|
|
106
107
|
recovery: value.recovery.map((action) => ({
|
|
107
108
|
...action,
|
|
108
|
-
command: qualifyItPayCommand(action.command, agentType),
|
|
109
|
+
command: qualifyBackendCommand(qualifyItPayCommand(action.command, agentType)),
|
|
109
110
|
})),
|
|
110
111
|
};
|
|
111
112
|
}
|
|
@@ -304,7 +305,7 @@ export function errorRecoveryActions(error) {
|
|
|
304
305
|
return [
|
|
305
306
|
{
|
|
306
307
|
id: "retry_after_backend_recovers",
|
|
307
|
-
label: "Retry after
|
|
308
|
+
label: "Retry after the selected official Backend is reachable",
|
|
308
309
|
command: "itpay readyz",
|
|
309
310
|
},
|
|
310
311
|
];
|
|
@@ -48,9 +48,9 @@ export function runInstall(target, options = {}) {
|
|
|
48
48
|
instruction: INSTRUCTIONS[normalized],
|
|
49
49
|
next: {
|
|
50
50
|
command: `itpay --agent-type ${normalized} readyz --json`,
|
|
51
|
-
reason: "
|
|
51
|
+
reason: "验证当前官方 ItPay API 的可用性",
|
|
52
52
|
},
|
|
53
|
-
recovery: [{ command: "itpay docs show install-and-setup", reason: "
|
|
53
|
+
recovery: [{ command: "itpay docs show install-and-setup", reason: "查看官方 Backend 和首次使用说明" }],
|
|
54
54
|
}, options);
|
|
55
55
|
}
|
|
56
56
|
function isInstallAgentType(value) {
|
|
@@ -2,10 +2,14 @@
|
|
|
2
2
|
import { writeCommandEnvelope } from "./guidance.js";
|
|
3
3
|
export async function runReadyz(backend, options = {}) {
|
|
4
4
|
const response = await backend.readyz();
|
|
5
|
+
const backendURL = options.backendURL ?? "https://app.itpay.ai";
|
|
6
|
+
const environment = options.environment ?? "production";
|
|
5
7
|
writeCommandEnvelope({
|
|
6
8
|
status: response.status,
|
|
7
|
-
result: { backend: "available", ...(options.agentType ? { agent_type: options.agentType } : {}) },
|
|
8
|
-
instruction:
|
|
9
|
+
result: { backend: "available", backend_url: backendURL, environment, ...(options.agentType ? { agent_type: options.agentType } : {}) },
|
|
10
|
+
instruction: environment === "development"
|
|
11
|
+
? "ItPay dev 可用;后续必须执行返回的完整命令,并继续使用同一个 dev Backend。先完整读取内置 ItPay Skill,再进入当前已支持的 buy 流程。"
|
|
12
|
+
: "ItPay 可用;先完整读取内置 ItPay Skill,再进入当前已支持的 buy 流程。sell 将来也使用同一入口,但当前尚未实现。",
|
|
9
13
|
next: { command: "itpay skill show itpay --json", reason: "加载完整操作与安全规则" },
|
|
10
14
|
recovery: [],
|
|
11
15
|
}, options);
|
package/dist/src/main.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// services/backend/internal/httpapi/handlers/*.go. Commands only
|
|
3
3
|
// orchestrate; HTTP and rendering live in src/client and src/render.
|
|
4
4
|
import { Command } from "commander";
|
|
5
|
-
import { CLI_VERSION, loadConfig, cartSessionPath, newBackendClient } from "./state/config.js";
|
|
5
|
+
import { BackendOverrideError, CLI_VERSION, loadConfig, cartSessionPath, newBackendClient } from "./state/config.js";
|
|
6
6
|
import { DeviceAuthority, DeviceAuthorizationError, DeviceStateError } from "./state/device_authority.js";
|
|
7
7
|
import { CartSession } from "./state/cart_session.js";
|
|
8
8
|
import { defaultHostForAgentType, normalizeHost, validateContext } from "./state/client_context.js";
|
|
@@ -83,6 +83,7 @@ function resolveCheckoutPresentationArgs(input) {
|
|
|
83
83
|
}
|
|
84
84
|
function reportCLIError(error, contract) {
|
|
85
85
|
const commandError = error instanceof CommandContractError ? error : undefined;
|
|
86
|
+
const backendOverrideError = error instanceof BackendOverrideError ? error : undefined;
|
|
86
87
|
const deviceError = error instanceof DeviceAuthorizationError ? error : undefined;
|
|
87
88
|
const stateError = error instanceof DeviceStateError ? error : undefined;
|
|
88
89
|
const httpRecovery = errorRecoveryActions(error).map((action) => ({
|
|
@@ -122,11 +123,11 @@ function reportCLIError(error, contract) {
|
|
|
122
123
|
: deviceError
|
|
123
124
|
? "Device 身份验证失败;停止重试,不要切换 Agent Type、删除状态或旋转私钥。"
|
|
124
125
|
: undefined;
|
|
125
|
-
if (contract || commandError) {
|
|
126
|
+
if (contract || commandError || backendOverrideError) {
|
|
126
127
|
writeCommandEnvelope({
|
|
127
128
|
status: "error",
|
|
128
129
|
error: {
|
|
129
|
-
code: incompatible ? "backend_contract_incompatible" : commandError?.code ?? (error instanceof HttpError ? error.code : stateError?.code ?? deviceError?.code ?? contract?.code ?? "command_failed"),
|
|
130
|
+
code: incompatible ? "backend_contract_incompatible" : backendOverrideError?.code ?? commandError?.code ?? (error instanceof HttpError ? error.code : stateError?.code ?? deviceError?.code ?? contract?.code ?? "command_failed"),
|
|
130
131
|
message: error instanceof Error ? error.message : String(error),
|
|
131
132
|
},
|
|
132
133
|
...(requiredCLIVersion ? {
|
|
@@ -164,7 +165,9 @@ function reportCLIError(error, contract) {
|
|
|
164
165
|
? "Provider 拒绝了本次请求,但未声明这是输入错误;向用户逐字报告 error.message 和 result.quota 并停止。不要修改输入、不要重试、不要创建新 Execution。"
|
|
165
166
|
: capabilityInputInvalid
|
|
166
167
|
? "输入未通过本地校验,上游尚未被调用且用户额度未变化。向用户逐字报告 error.message 并停止,不要原样重试或运行其他恢复命令。用户提供修正后的输入后,继续使用当前未结束的 Execution。"
|
|
167
|
-
:
|
|
168
|
+
: backendOverrideError
|
|
169
|
+
? "移除 ITPAY_BACKEND_URL 使用正式环境,或准确设置为 https://dev.itpay.ai。"
|
|
170
|
+
: commandError?.instruction ?? authorizationInstruction ?? contract?.instruction ?? "检查命令参数后重试。",
|
|
168
171
|
next: null,
|
|
169
172
|
recovery: incompatible
|
|
170
173
|
? requiredCLIVersion
|
|
@@ -172,9 +175,9 @@ function reportCLIError(error, contract) {
|
|
|
172
175
|
: []
|
|
173
176
|
: backendInternal || providerConnectionUnavailable || providerTemporary || providerInputRejected || providerContractMismatch || providerRejected || capabilityInputInvalid
|
|
174
177
|
? []
|
|
175
|
-
: commandError?.recovery ?? (stateError ? stateRecovery : deviceError ? deviceRecovery : identityRecovery ? httpRecovery : contract?.recovery ?? []),
|
|
178
|
+
: backendOverrideError ? [] : commandError?.recovery ?? (stateError ? stateRecovery : deviceError ? deviceRecovery : identityRecovery ? httpRecovery : contract?.recovery ?? []),
|
|
176
179
|
}, {
|
|
177
|
-
...(contract?.jsonOutput !== undefined ? { jsonOutput: contract.jsonOutput } : {}),
|
|
180
|
+
...(contract?.jsonOutput !== undefined ? { jsonOutput: contract.jsonOutput } : backendOverrideError ? { jsonOutput: process.argv.includes("--json") } : {}),
|
|
178
181
|
output: (text) => { process.stderr.write(text); },
|
|
179
182
|
});
|
|
180
183
|
process.exitCode = 1;
|
|
@@ -209,31 +212,34 @@ program
|
|
|
209
212
|
const config = loadConfig();
|
|
210
213
|
const backend = newBackendClient(config);
|
|
211
214
|
try {
|
|
212
|
-
await runReadyz(backend, {
|
|
215
|
+
await runReadyz(backend, {
|
|
216
|
+
jsonOutput: Boolean(options.json), backendURL: config.baseURL, environment: config.environment,
|
|
217
|
+
...(config.agentType ? { agentType: config.agentType } : {}),
|
|
218
|
+
});
|
|
213
219
|
}
|
|
214
220
|
catch (error) {
|
|
215
221
|
reportCLIError(error, {
|
|
216
222
|
jsonOutput: Boolean(options.json),
|
|
217
223
|
code: "backend_unavailable",
|
|
218
|
-
instruction:
|
|
224
|
+
instruction: `当前官方 Backend ${config.baseURL} 不可用;恢复前不要继续下单,也不要切换环境。`,
|
|
219
225
|
recovery: [
|
|
220
|
-
{ command: "itpay readyz", reason: "
|
|
226
|
+
{ command: "itpay readyz", reason: "重试当前官方 Backend 的可用性检查" },
|
|
221
227
|
],
|
|
222
228
|
});
|
|
223
229
|
}
|
|
224
230
|
});
|
|
225
231
|
// --- device ---------------------------------------------------------------
|
|
226
|
-
const deviceCmd = program.command("device").description("Recover
|
|
232
|
+
const deviceCmd = program.command("device").description("Recover the current official Backend registration after an operator-confirmed reset");
|
|
227
233
|
deviceCmd
|
|
228
234
|
.command("recover")
|
|
229
|
-
.description("Forget only the
|
|
235
|
+
.description("Forget only the current official Backend registration while preserving the local private key")
|
|
230
236
|
.option("--confirm-backend-reset", "confirm that an operator reset the selected Backend registration database")
|
|
231
237
|
.option("--json", "output JSON instead of terminal text")
|
|
232
238
|
.action(async (options) => {
|
|
233
239
|
const config = loadConfig();
|
|
234
240
|
try {
|
|
235
241
|
if (!config.agentType) {
|
|
236
|
-
throw new CommandContractError("agent_type_required",
|
|
242
|
+
throw new CommandContractError("agent_type_required", `agent type is required for ${config.baseURL} Device recovery`, "如实声明当前 Agent Type;恢复后必须用同一类型重新登记。", [{ command: "itpay install --json", reason: "选择当前真实 Agent Type" }]);
|
|
237
243
|
}
|
|
238
244
|
if (!options.confirmBackendReset) {
|
|
239
245
|
throw new CommandContractError("backend_reset_confirmation_required", "--confirm-backend-reset is required", "仅在运营已确认当前 Backend 的 Device 登记数据库被重建或清空后执行;普通 session 失效或 revoked 不得使用。", [{ command: "itpay docs show identity-and-sessions --json", reason: "检查适用边界" }]);
|
package/dist/src/state/config.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// CLI configuration loader.
|
|
2
|
-
//
|
|
1
|
+
// CLI configuration loader. Production defaults to app.itpay.ai; the only
|
|
2
|
+
// allowed override is the official dev Backend. Checkout
|
|
3
3
|
// display-token persistence belongs to the cart session file, protected with
|
|
4
4
|
// owner-only permissions. Provider secrets are explicitly out of scope here.
|
|
5
5
|
import { homedir } from "node:os";
|
|
@@ -11,21 +11,54 @@ import { declaredAgentType } from "./agent_type.js";
|
|
|
11
11
|
import { DeviceAuthority } from "./device_authority.js";
|
|
12
12
|
import { OperationJournal } from "./operation_journal.js";
|
|
13
13
|
export const DEFAULT_BASE_URL = "https://app.itpay.ai";
|
|
14
|
-
export const
|
|
14
|
+
export const DEV_BASE_URL = "https://dev.itpay.ai";
|
|
15
|
+
export const CLI_VERSION = "2.0.15";
|
|
15
16
|
export const API_CONTRACT_REVISION = "sha256:7f4c40b082292bf823631bcd37d452f4a8537153e30636d5eb3a2b24a77ce602";
|
|
16
17
|
const CART_SESSION_DEFAULT_DIR = ".itpay-v3";
|
|
17
18
|
const CART_SESSION_FILENAME = "cart.json";
|
|
18
19
|
const OPERATION_JOURNAL_FILENAME = "operations.json";
|
|
20
|
+
export class BackendOverrideError extends Error {
|
|
21
|
+
code = "backend_override_forbidden";
|
|
22
|
+
constructor() {
|
|
23
|
+
super(`ITPAY_BACKEND_URL only supports ${DEFAULT_BASE_URL} or ${DEV_BASE_URL}`);
|
|
24
|
+
this.name = "BackendOverrideError";
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export function resolveBackendURL(env = process.env) {
|
|
28
|
+
const requested = env.ITPAY_BACKEND_URL?.trim();
|
|
29
|
+
if (!requested || requested === DEFAULT_BASE_URL || requested === `${DEFAULT_BASE_URL}/`)
|
|
30
|
+
return DEFAULT_BASE_URL;
|
|
31
|
+
if (requested === DEV_BASE_URL || requested === `${DEV_BASE_URL}/`)
|
|
32
|
+
return DEV_BASE_URL;
|
|
33
|
+
throw new BackendOverrideError();
|
|
34
|
+
}
|
|
35
|
+
export function qualifyBackendCommand(command, env = process.env) {
|
|
36
|
+
const requested = env.ITPAY_BACKEND_URL?.trim();
|
|
37
|
+
if (requested !== DEV_BASE_URL && requested !== `${DEV_BASE_URL}/`)
|
|
38
|
+
return command;
|
|
39
|
+
if (!command.startsWith("itpay ") || command.startsWith(`ITPAY_BACKEND_URL=${DEV_BASE_URL} `))
|
|
40
|
+
return command;
|
|
41
|
+
return `ITPAY_BACKEND_URL=${DEV_BASE_URL} ${command}`;
|
|
42
|
+
}
|
|
43
|
+
function stateFilename(filename, baseURL) {
|
|
44
|
+
if (baseURL !== DEV_BASE_URL)
|
|
45
|
+
return filename;
|
|
46
|
+
const dot = filename.lastIndexOf(".");
|
|
47
|
+
return dot < 0 ? `${filename}.dev` : `${filename.slice(0, dot)}.dev${filename.slice(dot)}`;
|
|
48
|
+
}
|
|
49
|
+
function stateDir(env) {
|
|
50
|
+
return resolve(env.HOME || homedir(), CART_SESSION_DEFAULT_DIR);
|
|
51
|
+
}
|
|
19
52
|
export function cartSessionPath(env = process.env) {
|
|
20
53
|
if (env.ITPAY_CART_SESSION_PATH) {
|
|
21
54
|
return resolve(env.ITPAY_CART_SESSION_PATH);
|
|
22
55
|
}
|
|
23
|
-
const dir =
|
|
56
|
+
const dir = stateDir(env);
|
|
24
57
|
mkdirSync(dir, { recursive: true });
|
|
25
|
-
return resolve(dir, CART_SESSION_FILENAME);
|
|
58
|
+
return resolve(dir, stateFilename(CART_SESSION_FILENAME, resolveBackendURL(env)));
|
|
26
59
|
}
|
|
27
60
|
export function loadConfig(env = process.env) {
|
|
28
|
-
const baseURL =
|
|
61
|
+
const baseURL = resolveBackendURL(env);
|
|
29
62
|
const bearerToken = env.ITPAY_BEARER_TOKEN || undefined;
|
|
30
63
|
const agentType = declaredAgentType(env);
|
|
31
64
|
const checkoutCurrency = env.ITPAY_CURRENCY || "CNY";
|
|
@@ -34,10 +67,11 @@ export function loadConfig(env = process.env) {
|
|
|
34
67
|
const ideImageDirOverride = env.ITPAY_IDE_IMAGE_DIR_OVERRIDE;
|
|
35
68
|
return {
|
|
36
69
|
baseURL,
|
|
70
|
+
environment: baseURL === DEV_BASE_URL ? "development" : "production",
|
|
37
71
|
...(agentType ? { agentType } : {}),
|
|
38
72
|
checkoutCurrency,
|
|
39
73
|
idempotencyKey,
|
|
40
|
-
...(!env.ITPAY_IDEMPOTENCY_KEY ? { operationJournal: new OperationJournal(resolve(
|
|
74
|
+
...(!env.ITPAY_IDEMPOTENCY_KEY ? { operationJournal: new OperationJournal(resolve(stateDir(env), stateFilename(OPERATION_JOURNAL_FILENAME, baseURL))) } : {}),
|
|
41
75
|
ideImageAttach,
|
|
42
76
|
...(ideImageDirOverride ? { ideImageDirOverride } : {}),
|
|
43
77
|
...(bearerToken ? { bearerToken } : {}),
|
|
@@ -4,16 +4,16 @@
|
|
|
4
4
|
"product_scope": "itpay is the single public CLI entry point, and $itpay is its user-facing Skill invocation. Under that one product entry point, the two top-level commerce actions are buy and sell: Buyer workflows are available now; Seller workflows will use the same entry point and are not implemented yet.",
|
|
5
5
|
"topic": "identity-and-sessions",
|
|
6
6
|
"title": "Device Identity And Session Recovery",
|
|
7
|
-
"purpose": "Explain stable local identity,
|
|
7
|
+
"purpose": "Explain stable local identity, official Backend-scoped registrations, Agent Type instances, and bounded automatic session recovery.",
|
|
8
8
|
"when_to_use": [
|
|
9
9
|
"A different Agent window or runtime starts using an existing CLI installation.",
|
|
10
10
|
"The CLI reports device_state_unwritable, or the Backend reports agent_identity_required, agent_device_session_required, or agent_device_revoked.",
|
|
11
|
-
"An operator confirms that the
|
|
11
|
+
"An operator confirms that the currently selected official Backend registration database was reset."
|
|
12
12
|
],
|
|
13
13
|
"identity_model": {
|
|
14
14
|
"local_key": "One owner-only Ed25519 private key for the local installation.",
|
|
15
|
-
"backend_registration": "One
|
|
16
|
-
"agent_instance": "One instance per agent_type under
|
|
15
|
+
"backend_registration": "One registration per official Backend: app.itpay.ai by default and dev.itpay.ai only with the exact test override.",
|
|
16
|
+
"agent_instance": "One instance per agent_type under each Backend registration; same-type windows and chats reuse it.",
|
|
17
17
|
"presentation": "Host and target route output only and never identify the Agent or provide business input."
|
|
18
18
|
},
|
|
19
19
|
"automatic_recovery": [
|
|
@@ -34,27 +34,27 @@
|
|
|
34
34
|
"success_signal": "the full Skill is returned and next keeps the same Agent Type"
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
|
-
"intent": "confirm
|
|
37
|
+
"intent": "confirm the selected official Backend is available",
|
|
38
38
|
"command": "itpay --agent-type <agent_type> readyz --json",
|
|
39
39
|
"success_signal": "Backend is available and onboarding returns to the Skill"
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
|
-
"intent": "recover after an operator-confirmed reset of the
|
|
42
|
+
"intent": "recover after an operator-confirmed reset of the selected official Backend registration database",
|
|
43
43
|
"command": "itpay --agent-type <agent_type> device recover --confirm-backend-reset --json",
|
|
44
|
-
"success_signal": "only the
|
|
44
|
+
"success_signal": "only the selected Backend registration is removed and the private key and other Backend registration remain"
|
|
45
45
|
}
|
|
46
46
|
],
|
|
47
47
|
"agent_rules": [
|
|
48
48
|
"Use the real runtime type and keep it stable across every command in the flow.",
|
|
49
49
|
"Keep the same CLI/Node launcher and Host-approved permission context for the whole flow.",
|
|
50
50
|
"Treat a new window, chat, task, or process of the same runtime as the same Agent Type, not a new identity.",
|
|
51
|
-
"Expect
|
|
52
|
-
"After automatic recovery fails, stop and report the exact code,
|
|
51
|
+
"Expect production traffic to use https://app.itpay.ai. Use https://dev.itpay.ai only for an explicit test and keep the complete returned Backend-prefixed command for that entire flow.",
|
|
52
|
+
"After automatic recovery fails, stop and report the exact code, selected official Backend, Agent Type, and command family without exposing private keys or tokens."
|
|
53
53
|
],
|
|
54
54
|
"forbidden": [
|
|
55
55
|
"Do not delete ~/.itpay-v3, rotate the key, switch Agent Type, or repeatedly retry to obtain fresh quota.",
|
|
56
56
|
"Do not use device recover for session expiry, revocation, quota recovery, or an unconfirmed Backend failure.",
|
|
57
|
-
"Do not redirect the CLI to
|
|
57
|
+
"Do not redirect the CLI to test, local, an IP, or any custom Backend; only the exact official dev.itpay.ai test override is allowed.",
|
|
58
58
|
"Do not use --target as identity or service input."
|
|
59
59
|
],
|
|
60
60
|
"next_docs": [
|
|
@@ -33,20 +33,19 @@
|
|
|
33
33
|
],
|
|
34
34
|
"agent_rules": [
|
|
35
35
|
"Install with npm install -g @itpay/cli.",
|
|
36
|
-
"
|
|
36
|
+
"Production defaults to https://app.itpay.ai. Testing may set ITPAY_BACKEND_URL to the exact official URL https://dev.itpay.ai; no other Backend is allowed.",
|
|
37
37
|
"If backend_contract_incompatible includes result.required_cli_version, stop all ItPay business commands and run only the exact npm install recovery returned by the CLI; never replace its version with latest.",
|
|
38
38
|
"After upgrading, require itpay --version to equal result.required_cli_version before running readyz again; never change Agent Type or Device identity to recover compatibility.",
|
|
39
|
-
"The production Backend is fixed to https://app.itpay.ai and cannot be redirected by runtime environment variables.",
|
|
40
39
|
"Use one exact type: codex-desktop, codex-cli, claude-code-desktop, claude-code-cli, or workbuddy.",
|
|
41
|
-
"One local private key is reused
|
|
42
|
-
"Within
|
|
40
|
+
"One local private key is reused, while Device registrations and quota lineage remain separate for app.itpay.ai and dev.itpay.ai.",
|
|
41
|
+
"Within each official Backend registration, each Agent Type has one Agent Instance; all windows and chats of the same type reuse it.",
|
|
43
42
|
"Agent Type identifies the runtime. Host controls rendering and target only identifies a presentation destination.",
|
|
44
43
|
"Keep the exact Agent Type in every next or recovery command; do not fall back to a type previously used by another runtime.",
|
|
45
44
|
"Do not change Agent Type or rotate local identity to reset quota or recover a failed command."
|
|
46
45
|
],
|
|
47
46
|
"forbidden": [
|
|
48
47
|
"Do not use codex, terminal, claude-code, or plain-chat as Agent Types.",
|
|
49
|
-
"Do not set or suggest
|
|
48
|
+
"Do not set or suggest any Backend except the default https://app.itpay.ai or the exact test override https://dev.itpay.ai.",
|
|
50
49
|
"Do not claim that install writes host configuration or registers a device; it only prints instructions.",
|
|
51
50
|
"Do not create a new identity for a different window, task, chat, or process of the same Agent Type."
|
|
52
51
|
],
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"required_state": {
|
|
13
13
|
"needs": [
|
|
14
14
|
"the real supported Agent Type",
|
|
15
|
-
"
|
|
15
|
+
"one official Backend: production https://app.itpay.ai by default, or explicit test https://dev.itpay.ai"
|
|
16
16
|
],
|
|
17
17
|
"must_not_need": [
|
|
18
18
|
"Admin access",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
},
|
|
23
23
|
"commands": [
|
|
24
24
|
{
|
|
25
|
-
"intent": "verify
|
|
25
|
+
"intent": "verify the selected official Backend availability",
|
|
26
26
|
"command": "itpay --agent-type <agent_type> readyz --json",
|
|
27
27
|
"success_signal": "status is ready and next points to the complete packaged ItPay Skill"
|
|
28
28
|
},
|
|
@@ -57,6 +57,7 @@
|
|
|
57
57
|
"Treat result as current facts, instruction as how to use those facts, next as the preferred executable action, and recovery as exceptional paths.",
|
|
58
58
|
"Run one state-changing command at a time. Treat next.command as the preferred continuation: execute it unchanged after filling required user data only when the current result has not already satisfied the user's goal.",
|
|
59
59
|
"Keep the same explicit Agent Type through next and recovery commands; same-type windows reuse one Backend Agent Instance.",
|
|
60
|
+
"When testing dev, execute every returned command unchanged so its ITPAY_BACKEND_URL=https://dev.itpay.ai prefix is preserved.",
|
|
60
61
|
"Use --target only for a Host presentation destination. Put capability business values in --input key=value exactly as required by the schema.",
|
|
61
62
|
"Start a separate Service Execution for each independent service intent; quota remains shared according to Backend identity policy.",
|
|
62
63
|
"Ask the user for required email or contact values and explain their purpose; never invent them.",
|
|
@@ -18,7 +18,7 @@ itpay cart remove --local --variant <catalog_variant_id> --offer <offer_id> [--j
|
|
|
18
18
|
|
|
19
19
|
| 参数 | 必填 | 说明 |
|
|
20
20
|
| --- | --- | --- |
|
|
21
|
-
| `--line <cart_item_id>` | 否 | canonical Cart line
|
|
21
|
+
| `--line <cart_item_id>` | 否 | canonical Cart line;省略时使用当前官方 Backend 对应本地状态中最后保存的 line。 |
|
|
22
22
|
| `--local` | 否 | 只修改显式本地草稿,不请求 Backend。 |
|
|
23
23
|
| `--variant <catalog_variant_id>` | local 时是 | 与 `--offer` 一起标识本地草稿 line。 |
|
|
24
24
|
| `--offer <offer_id>` | local 时是 | 与 `--variant` 一起标识本地草稿 line。 |
|
|
@@ -10,6 +10,6 @@
|
|
|
10
10
|
itpay --agent-type <agent_type> device recover --confirm-backend-reset --json
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
命令只作用于当前官方 Backend 的 Device registration,并保留本地 Ed25519 私钥、Cart 和业务资源。默认是 `https://app.itpay.ai`;显式测试可使用准确的 `ITPAY_BACKEND_URL=https://dev.itpay.ai`。该命令不访问 Backend、不自动创建新身份;返回的只读 `services list` 会保留同一 Backend,是重新登记入口。
|
|
14
14
|
|
|
15
15
|
缺少确认参数返回 `backend_reset_confirmation_required`。普通 session 失效由 CLI 自动续期;revoked、quota、权限或未知 Backend 故障不得使用本命令。所有 Agent Type 使用相同输入和输出合同。
|
|
@@ -37,12 +37,12 @@ itpay install [target] [--json]
|
|
|
37
37
|
"instruction": "在 Codex Desktop 中始终传这个 Agent Type;付款时把返回的二维码和链接实际展示到当前对话。",
|
|
38
38
|
"next": {
|
|
39
39
|
"command": "itpay --agent-type codex-desktop readyz --json",
|
|
40
|
-
"reason": "
|
|
40
|
+
"reason": "验证当前官方 ItPay API 的可用性"
|
|
41
41
|
},
|
|
42
42
|
"recovery": [
|
|
43
43
|
{
|
|
44
44
|
"command": "itpay docs show install-and-setup",
|
|
45
|
-
"reason": "
|
|
45
|
+
"reason": "查看官方 Backend 和首次使用说明"
|
|
46
46
|
}
|
|
47
47
|
]
|
|
48
48
|
}
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
## 范围与意义
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
检查当前官方 Backend 是否可用。默认使用生产环境 `https://app.itpay.ai`;仅测试时可通过 `ITPAY_BACKEND_URL=https://dev.itpay.ai` 选择官方开发环境。它只调用 `/v1/readyz` 做 liveness 诊断,不执行平台兼容性 gate、不登记设备、不创建业务资源;需要服务端合同的命令仍会在各自入口严格检查 compatibility。
|
|
8
8
|
|
|
9
|
-
**上游:** CLI 安装;Backend
|
|
9
|
+
**上游:** CLI 安装;Backend 只能是官方 `https://app.itpay.ai` 或 `https://dev.itpay.ai`,其他 override 在网络或本地状态写入前被拒绝。
|
|
10
10
|
**下游:** 完整 `itpay` Skill,随后选择 Agent Type 或进入当前已支持的 Buyer Catalog。
|
|
11
11
|
|
|
12
12
|
## 语法与参数
|
|
@@ -24,16 +24,43 @@ itpay readyz [--json]
|
|
|
24
24
|
```json
|
|
25
25
|
{
|
|
26
26
|
"status": "ready",
|
|
27
|
-
"result": { "backend": "available" },
|
|
27
|
+
"result": { "backend": "available", "backend_url": "https://app.itpay.ai", "environment": "production" },
|
|
28
28
|
"instruction": "ItPay 可用;先完整读取内置 ItPay Skill,再进入当前已支持的 buy 流程。sell 将来也使用同一入口,但当前尚未实现。",
|
|
29
29
|
"next": { "command": "itpay skill show itpay --json", "reason": "加载完整操作与安全规则" },
|
|
30
30
|
"recovery": []
|
|
31
31
|
}
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
+
开发环境返回同一 envelope,但明确标记环境并在每个后续命令中保留 dev Backend:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"status": "ready",
|
|
39
|
+
"result": { "backend": "available", "backend_url": "https://dev.itpay.ai", "environment": "development" },
|
|
40
|
+
"instruction": "ItPay dev 可用;后续必须执行返回的完整命令,并继续使用同一个 dev Backend。先完整读取内置 ItPay Skill,再进入当前已支持的 buy 流程。",
|
|
41
|
+
"next": { "command": "ITPAY_BACKEND_URL=https://dev.itpay.ai itpay skill show itpay --json", "reason": "加载完整操作与安全规则" },
|
|
42
|
+
"recovery": []
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
34
46
|
## 异常处理
|
|
35
47
|
|
|
36
|
-
连接失败时返回 `backend_unavailable
|
|
48
|
+
连接失败时返回 `backend_unavailable`,要求等待当前官方 Backend 恢复后重试同一完整命令,不得在失败时切换环境或继续下单。
|
|
49
|
+
|
|
50
|
+
非官方 URL 返回 `backend_override_forbidden`,且不提供自动 recovery:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"status": "error",
|
|
55
|
+
"error": {
|
|
56
|
+
"code": "backend_override_forbidden",
|
|
57
|
+
"message": "ITPAY_BACKEND_URL only supports https://app.itpay.ai or https://dev.itpay.ai"
|
|
58
|
+
},
|
|
59
|
+
"instruction": "移除 ITPAY_BACKEND_URL 使用正式环境,或准确设置为 https://dev.itpay.ai。",
|
|
60
|
+
"next": null,
|
|
61
|
+
"recovery": []
|
|
62
|
+
}
|
|
63
|
+
```
|
|
37
64
|
|
|
38
65
|
CLI 已取得 Backend 的兼容性合同、但当前版本或 contract hash 不匹配时,返回一个可执行且版本固定的恢复动作:
|
|
39
66
|
|
|
@@ -42,17 +69,17 @@ CLI 已取得 Backend 的兼容性合同、但当前版本或 contract hash 不
|
|
|
42
69
|
"status": "error",
|
|
43
70
|
"error": {
|
|
44
71
|
"code": "backend_contract_incompatible",
|
|
45
|
-
"message": "CLI 2.0.
|
|
72
|
+
"message": "CLI 2.0.15 contract sha256:client is incompatible with platform v3.example contract sha256:server (minimum CLI 2.0.16, maximum major 2)"
|
|
46
73
|
},
|
|
47
74
|
"result": {
|
|
48
|
-
"current_cli_version": "2.0.
|
|
49
|
-
"required_cli_version": "2.0.
|
|
75
|
+
"current_cli_version": "2.0.15",
|
|
76
|
+
"required_cli_version": "2.0.16"
|
|
50
77
|
},
|
|
51
78
|
"instruction": "当前 CLI 与 Backend 合约不兼容。停止所有 ItPay 业务命令;只执行 recovery.command,将 @itpay/cli 更新到 Backend 指定的精确版本。安装完成后确认 itpay --version 与 result.required_cli_version 完全一致,再重新运行 readyz。不要安装 latest、猜测版本、切换 Agent Type 或删除 Device 身份。",
|
|
52
79
|
"next": null,
|
|
53
80
|
"recovery": [
|
|
54
81
|
{
|
|
55
|
-
"command": "npm install -g @itpay/cli@2.0.
|
|
82
|
+
"command": "npm install -g @itpay/cli@2.0.16",
|
|
56
83
|
"reason": "安装 Backend 指定的兼容 CLI 版本"
|
|
57
84
|
}
|
|
58
85
|
]
|