@itpay/cli 2.1.41 → 2.1.44
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 +12 -5
- package/assets/sell-preview/index.html +6 -0
- package/assets/sell-preview/preview.js +9 -0
- package/bin/darwin-amd64/itpay-sell +0 -0
- package/bin/darwin-arm64/itpay-sell +0 -0
- package/bin/linux-amd64/itpay-sell +0 -0
- package/bin/linux-arm64/itpay-sell +0 -0
- package/bin/windows-amd64/itpay-sell.exe +0 -0
- package/dist/src/client/backend.js +38 -2
- package/dist/src/client/http.js +2 -0
- package/dist/src/commands/aftercare.js +12 -0
- package/dist/src/commands/buy.js +17 -58
- package/dist/src/commands/cart.js +17 -15
- package/dist/src/commands/catalog.js +39 -14
- package/dist/src/commands/checkout.js +146 -5
- package/dist/src/commands/checkout_handoff.js +11 -61
- package/dist/src/commands/docs.js +7 -18
- package/dist/src/commands/guidance.js +1 -134
- package/dist/src/commands/install.js +6 -3
- package/dist/src/commands/order.js +34 -3
- package/dist/src/commands/orders.js +4 -9
- package/dist/src/commands/pay.js +1 -1
- package/dist/src/commands/presentation.js +153 -0
- package/dist/src/commands/rail_catalog.js +1 -0
- package/dist/src/commands/readyz.js +1 -1
- package/dist/src/commands/refund.js +13 -57
- package/dist/src/commands/services/actions.js +133 -0
- package/dist/src/commands/services/commerce.js +197 -0
- package/dist/src/commands/services/lifecycle.js +418 -0
- package/dist/src/commands/services/results.js +130 -0
- package/dist/src/commands/services.js +14 -1068
- package/dist/src/commands/skill.js +8 -5
- package/dist/src/commands/vault.js +27 -20
- package/dist/src/commands/vault_handoff.js +18 -0
- package/dist/src/main.js +332 -46
- package/dist/src/render/browser.js +65 -0
- package/dist/src/render/checkout_handoff.js +101 -0
- package/dist/src/render/checkout_plan.js +47 -0
- package/dist/src/render/markdown.js +0 -3
- package/dist/src/render/qr.js +1 -1
- package/dist/src/sell/commands.js +80 -0
- package/dist/src/sell/contract.js +86 -0
- package/dist/src/sell/local.js +260 -0
- package/dist/src/sell/mcp.js +49 -0
- package/dist/src/sell/preview.js +70 -0
- package/dist/src/sell/sync.js +145 -0
- package/dist/src/services/adapter.js +1 -0
- package/dist/src/services/presentation.js +198 -0
- package/dist/src/services/rail/actions.js +51 -0
- package/dist/src/services/rail/adapter.js +36 -0
- package/dist/src/services/rail/aftercare.js +45 -0
- package/dist/src/services/rail/catalog.js +261 -0
- package/dist/src/services/rail/checkout.js +19 -0
- package/dist/src/services/rail/fulfillment.js +76 -0
- package/dist/src/services/rail/guide.js +110 -0
- package/dist/src/services/rail/invocation.js +54 -0
- package/dist/src/services/rail/page.js +76 -0
- package/dist/src/services/rail/pagination.js +6 -0
- package/dist/src/services/rail/query.js +71 -0
- package/dist/src/services/rail/readers.js +107 -0
- package/dist/src/services/rail/reading.js +125 -0
- package/dist/src/services/rail/recovery.js +51 -0
- package/dist/src/services/rail/results.js +378 -0
- package/dist/src/services/rail/review.js +268 -0
- package/dist/src/services/rail/saved.js +49 -0
- package/dist/src/services/rail/wait.js +11 -0
- package/dist/src/services/registry.js +31 -0
- package/dist/src/services/schema.js +21 -0
- package/dist/src/services/shared/envelope.js +184 -0
- package/dist/src/services/shared/input.js +39 -0
- package/dist/src/services/shared/pagination.js +28 -0
- package/dist/src/services/shared/platform.js +365 -0
- package/dist/src/services/shared/refund.js +40 -0
- package/dist/src/services/shared/workflow.js +28 -0
- package/dist/src/state/account_auth.js +354 -0
- package/dist/src/state/cart_session.js +4 -1
- package/dist/src/state/client_context.js +72 -0
- package/dist/src/state/config.js +44 -14
- package/dist/src/state/device_authority.js +402 -72
- package/dist/src/state/task_journal.js +90 -0
- package/docs/agent/buyer/cart-checkout.json +8 -6
- package/docs/agent/buyer/catalog-list.json +29 -9
- package/docs/agent/buyer/identity-and-sessions.json +26 -9
- package/docs/agent/buyer/install-and-setup.json +17 -15
- package/docs/agent/buyer/orders-refunds.json +25 -9
- package/docs/agent/buyer/payment-flow.json +6 -4
- package/docs/agent/buyer/purchased-content.json +18 -4
- package/docs/agent/buyer/quickstart.json +26 -17
- package/docs/agent/buyer/rail-booking.json +176 -0
- package/docs/agent/buyer/rail-fast-checkout.json +48 -0
- package/docs/agent/buyer/render-hosts.json +23 -12
- package/docs/agent/buyer/service-feedback.json +4 -3
- package/docs/cli-reference/agent-types.md +7 -2
- package/docs/cli-reference/commands/aftercare.md +15 -0
- package/docs/cli-reference/commands/auth.md +96 -0
- package/docs/cli-reference/commands/buy.md +2 -1
- package/docs/cli-reference/commands/cart/add.md +5 -1
- package/docs/cli-reference/commands/cart/clear.md +1 -1
- package/docs/cli-reference/commands/cart/index.md +1 -1
- package/docs/cli-reference/commands/cart/next.md +5 -1
- package/docs/cli-reference/commands/cart/remove.md +1 -1
- package/docs/cli-reference/commands/cart/show.md +1 -1
- package/docs/cli-reference/commands/catalog/index.md +1 -1
- package/docs/cli-reference/commands/catalog/list.md +2 -2
- package/docs/cli-reference/commands/checkout.md +12 -2
- package/docs/cli-reference/commands/device.md +18 -11
- package/docs/cli-reference/commands/docs/index.md +1 -1
- package/docs/cli-reference/commands/docs/list.md +1 -1
- package/docs/cli-reference/commands/docs/search.md +1 -1
- package/docs/cli-reference/commands/docs/show.md +1 -1
- package/docs/cli-reference/commands/install.md +8 -6
- package/docs/cli-reference/commands/next.md +1 -1
- package/docs/cli-reference/commands/order.md +1 -1
- package/docs/cli-reference/commands/pay.md +1 -1
- package/docs/cli-reference/commands/readyz.md +11 -11
- package/docs/cli-reference/commands/refund/cancel.md +1 -1
- package/docs/cli-reference/commands/refund/create.md +1 -1
- package/docs/cli-reference/commands/refund/get.md +2 -2
- package/docs/cli-reference/commands/refund/index.md +1 -1
- package/docs/cli-reference/commands/refund/list.md +1 -1
- package/docs/cli-reference/commands/refund/watch.md +1 -1
- package/docs/cli-reference/commands/sell.md +1364 -0
- package/docs/cli-reference/commands/services/action.md +24 -3
- package/docs/cli-reference/commands/services/checkout.md +17 -2
- package/docs/cli-reference/commands/services/events.md +1 -1
- package/docs/cli-reference/commands/services/get.md +4 -2
- package/docs/cli-reference/commands/services/index.md +4 -3
- package/docs/cli-reference/commands/services/invoke.md +6 -4
- package/docs/cli-reference/commands/services/list.md +1 -1
- package/docs/cli-reference/commands/services/next.md +78 -12
- package/docs/cli-reference/commands/services/page.md +71 -0
- package/docs/cli-reference/commands/services/quote.md +4 -4
- package/docs/cli-reference/commands/services/read-result.md +17 -6
- package/docs/cli-reference/commands/services/run.md +152 -0
- package/docs/cli-reference/commands/services/start.md +5 -3
- package/docs/cli-reference/commands/vault/access.md +5 -1
- package/docs/cli-reference/conventions.md +4 -6
- package/docs/cli-reference/index.md +10 -1
- package/docs/sell.md +84 -0
- package/package.json +20 -12
- package/skills/itpay/SKILL.md +112 -102
- package/docs/skill-bundle-rollout/01-mcp-authentication.md +0 -134
- package/docs/skill-bundle-rollout/02-platform-bundle-repositories.md +0 -210
- package/docs/skill-bundle-rollout/03-platform-publishing.md +0 -161
- package/docs/skill-bundle-rollout/04-first-wave-platforms.md +0 -69
- package/docs/skill-bundle-rollout/05-sync-operations.md +0 -62
- package/docs/skill-bundle-rollout/README.md +0 -151
- /package/bin/{itp → itp.mjs} +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { dirname, resolve } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { CODEX_WAIT_GUIDANCE } from "./install.js";
|
|
4
5
|
import { declaredAgentType } from "../state/agent_type.js";
|
|
5
6
|
import { CommandContractError, writeCommandEnvelope } from "./guidance.js";
|
|
6
7
|
const commandDir = dirname(fileURLToPath(import.meta.url));
|
|
@@ -19,12 +20,14 @@ export function runSkillShow(name, options = {}) {
|
|
|
19
20
|
}
|
|
20
21
|
validateSkill(content);
|
|
21
22
|
const agentType = options.agentType ?? declaredAgentType();
|
|
23
|
+
if (agentType?.startsWith("codex-"))
|
|
24
|
+
content += `\n## Codex command continuation\n\n${CODEX_WAIT_GUIDANCE}\n`;
|
|
22
25
|
const envelope = {
|
|
23
26
|
status: "shown",
|
|
24
27
|
result: { skill: ITPAY_SKILL, content },
|
|
25
28
|
instruction: agentType
|
|
26
29
|
? agentType === "workbuddy"
|
|
27
|
-
? "完整读取并遵守 Skill
|
|
30
|
+
? "完整读取并遵守 Skill;按用户意图选择第一条命令。保持 workbuddy 和同一 CLI launcher,并为 ~/.itpay-v3 申请宿主允许的持久化权限;权限被拒时报告受阻操作,不删除 identity。"
|
|
28
31
|
: `完整读取并遵守 Skill;把自己视为服务用户的代理,先理解用户意图和解释用户权益,再选择购买、已购内容、订单或退款对应的第一条命令。当前 Agent Type 是 ${agentType},后续命令保持不变。`
|
|
29
32
|
: "完整读取并遵守 Skill;先如实选择当前运行环境对应的 Agent Type。",
|
|
30
33
|
next: agentType
|
|
@@ -46,10 +49,10 @@ function findSkillPath() {
|
|
|
46
49
|
return directPath;
|
|
47
50
|
return resolve(configuredRoot, ITPAY_SKILL, "SKILL.md");
|
|
48
51
|
}
|
|
49
|
-
const
|
|
50
|
-
if (existsSync(
|
|
51
|
-
return
|
|
52
|
-
return resolve(commandDir, "..", "..", "
|
|
52
|
+
const packagePath = resolve(commandDir, "..", "..", "..", "skills", ITPAY_SKILL, "SKILL.md");
|
|
53
|
+
if (existsSync(packagePath))
|
|
54
|
+
return packagePath;
|
|
55
|
+
return resolve(commandDir, "..", "..", "skills", ITPAY_SKILL, "SKILL.md");
|
|
53
56
|
}
|
|
54
57
|
function validateSkill(content) {
|
|
55
58
|
const frontmatter = content.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/)?.[1];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { HttpError } from "../client/http.js";
|
|
2
|
-
import { requiresTarget } from "../state/client_context.js";
|
|
2
|
+
import { requiresTarget, validateContext } from "../state/client_context.js";
|
|
3
3
|
import { formatMoney } from "../render/output.js";
|
|
4
|
-
import { CommandContractError, writeCommandEnvelope } from "./guidance.js";
|
|
4
|
+
import { CommandContractError, shellArgument, writeCommandEnvelope } from "./guidance.js";
|
|
5
5
|
import { buildVaultHandoff } from "./vault_handoff.js";
|
|
6
6
|
function outputOptions(options, plainResult) {
|
|
7
7
|
return {
|
|
@@ -19,21 +19,21 @@ export async function runVaultList(backend, input) {
|
|
|
19
19
|
const value = await backend.listBuyerVaultArtifacts(input);
|
|
20
20
|
writeCommandEnvelope({
|
|
21
21
|
status: value.items.length ? "vault_listed" : "no_vault_artifacts",
|
|
22
|
-
result: { items: value.items, next_cursor: value.next_cursor || null },
|
|
22
|
+
result: { items: value.items.map(item => ({ ...item, amount: formatMoney(item.amount_minor, item.currency), reader: { command: vaultReadCommand(item.artifact_ref, [], input), reason: "读取这一已购内容" } })), next_cursor: value.next_cursor || null },
|
|
23
23
|
instruction: value.items.length
|
|
24
|
-
? "
|
|
24
|
+
? "用编号、服务名称、内容主体、购买时间、金额和订单号说明匹配结果,不要向用户显示内部内容标识。一个精确匹配可按用户原始查看意图继续读取;已有任务可明确匹配时读取对应行;只有真实歧义才让用户选择。"
|
|
25
25
|
: "当前账号没有匹配的已购内容。向用户说明没有找到,不要猜测内容标识、自动购买或发起新的服务查询。",
|
|
26
|
-
next: null,
|
|
26
|
+
next: value.next_cursor ? { command: `itpay vault list --limit ${input.limit}${input.query ? ` --query ${shellArgument(input.query)}` : ""} --cursor ${shellArgument(value.next_cursor)}${contextFlags(input)} --json`, reason: "读取同一筛选的下一页" } : null,
|
|
27
27
|
recovery: [],
|
|
28
|
-
}, outputOptions(input
|
|
28
|
+
}, outputOptions(input));
|
|
29
29
|
}
|
|
30
30
|
catch (error) {
|
|
31
31
|
if (error instanceof HttpError && error.code === "vault_authorization_required") {
|
|
32
32
|
writeCommandEnvelope({
|
|
33
33
|
status: "human_authorization_required",
|
|
34
34
|
result: { intent: "list_purchased_content", query: input.query ?? "" },
|
|
35
|
-
instruction:
|
|
36
|
-
|
|
35
|
+
instruction: `需要用户确认一次身份和只读权限。按当前动作或待填模板生成官方入口,不要声称链接已经创建;用户完成后重新运行原始 vault list 命令。${accessContextInstruction(input)}`,
|
|
36
|
+
...vaultAccessGuidance(undefined, input), recovery: [],
|
|
37
37
|
}, outputOptions(input));
|
|
38
38
|
return;
|
|
39
39
|
}
|
|
@@ -41,6 +41,9 @@ export async function runVaultList(backend, input) {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
export async function runVaultAccess(backend, artifactRef, options) {
|
|
44
|
+
const issue = validateContext(options.host, options.target);
|
|
45
|
+
if (issue)
|
|
46
|
+
throw new CommandContractError(issue.code, issue.message, "先补齐当前可信会话的真实宿主和目标;尚未创建授权请求。", [], { schema_version: "itpay.interaction.v1", stage: "input_required", input_template: { command: vaultAccessCommand(artifactRef, options), required_input: issue.code === "target_required" ? ["target"] : ["host"], executable: false } });
|
|
44
47
|
const value = await backend.createVaultAccessRequest(artifactRef
|
|
45
48
|
? { purpose: "artifact_reveal", artifact_ref: artifactRef }
|
|
46
49
|
: { purpose: "account_window" });
|
|
@@ -90,23 +93,23 @@ export async function runVaultRead(backend, artifactRef, sections, options) {
|
|
|
90
93
|
: value.status === "result_preparing"
|
|
91
94
|
? "这份已购内容仍在准备。稍后只重试同一 read,不要重新授权、购买或调用 Provider。"
|
|
92
95
|
: "这份已购内容当前不可用。停止,不要重试、重新购买或绕过退款锁。",
|
|
93
|
-
next: null, recovery: [],
|
|
96
|
+
next: value.status === "result_preparing" ? { command: vaultReadCommand(artifactRef, normalized, options), reason: "稍后读取同一内容及原sections;不重新授权或购买" } : null, recovery: [],
|
|
94
97
|
}, outputOptions(options));
|
|
95
98
|
}
|
|
96
99
|
catch (error) {
|
|
97
100
|
if (error instanceof HttpError && error.code === "artifact_authorization_required") {
|
|
98
101
|
writeCommandEnvelope({
|
|
99
102
|
status: "human_authorization_required", result: { artifact_ref: artifactRef },
|
|
100
|
-
instruction:
|
|
101
|
-
|
|
103
|
+
instruction: `这份内容需要用户单独确认读取权限。按当前动作或待填模板生成一次官方入口;用户完成后重新运行原始 read,不要重复创建授权请求。${accessContextInstruction(options)}`,
|
|
104
|
+
...vaultAccessGuidance(artifactRef, options), recovery: [],
|
|
102
105
|
}, outputOptions(options));
|
|
103
106
|
return;
|
|
104
107
|
}
|
|
105
108
|
if (error instanceof HttpError && error.code === "vault_authorization_required") {
|
|
106
109
|
writeCommandEnvelope({
|
|
107
110
|
status: "human_authorization_required", result: { artifact_ref: artifactRef },
|
|
108
|
-
instruction:
|
|
109
|
-
|
|
111
|
+
instruction: `账号读取授权已缺失或过期。按当前动作或待填模板生成一次官方入口;用户完成后重新运行原始 read。${accessContextInstruction(options)}`,
|
|
112
|
+
...vaultAccessGuidance(undefined, options), recovery: [],
|
|
110
113
|
}, outputOptions(options));
|
|
111
114
|
return;
|
|
112
115
|
}
|
|
@@ -121,7 +124,7 @@ export function vaultAccessCommand(artifactRef, options) {
|
|
|
121
124
|
const host = options.host ?? (openClaw ? "<host>" : undefined);
|
|
122
125
|
if (host)
|
|
123
126
|
parts.push("--host", host);
|
|
124
|
-
const target = options.target ?? (openClaw &&
|
|
127
|
+
const target = options.target ?? (((openClaw && !options.host) || (options.host && requiresTarget(options.host))) ? "<target>" : undefined);
|
|
125
128
|
if (target)
|
|
126
129
|
parts.push("--target", shellArgument(target));
|
|
127
130
|
parts.push("--json");
|
|
@@ -132,10 +135,14 @@ export function accessContextInstruction(options) {
|
|
|
132
135
|
? " 将 <host> 和 <target> 替换为当前可信 OpenClaw 会话的真实值,不要照抄占位符或猜测目标。"
|
|
133
136
|
: "";
|
|
134
137
|
}
|
|
135
|
-
function
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
138
|
+
function contextFlags(options) {
|
|
139
|
+
return `${options.host ? ` --host ${options.host}` : ""}${options.target ? ` --target ${shellArgument(options.target)}` : ""}`;
|
|
140
|
+
}
|
|
141
|
+
function vaultReadCommand(artifact, sections, options) {
|
|
142
|
+
return `itpay vault read --artifact ${shellArgument(artifact)}${sections.map(section => ` --section ${shellArgument(section)}`).join("")}${contextFlags(options)} --json`;
|
|
143
|
+
}
|
|
144
|
+
export function vaultAccessGuidance(artifact, options) {
|
|
145
|
+
const command = vaultAccessCommand(artifact, options);
|
|
146
|
+
const missing = [...(options.agentType === "openclaw" && !options.host ? ["host"] : []), ...(options.host && requiresTarget(options.host) && !options.target || options.agentType === "openclaw" && !options.host && !options.target ? ["target"] : [])];
|
|
147
|
+
return missing.length ? { next: null, interaction: { schema_version: "itpay.interaction.v1", stage: "input_required", input_template: { command, required_input: missing, executable: false } } } : { next: { command, reason: "创建一次官方只读授权入口;用户完成后恢复原reader" } };
|
|
141
148
|
}
|
|
@@ -20,6 +20,13 @@ export async function buildVaultHandoff(input) {
|
|
|
20
20
|
instruction: "向用户说明这是查看已购内容的只读授权,然后立即用 ZCode 内置浏览器打开 handoff.url。确认已发起打开后停止等待;不要只粘贴文字链接,也不要下载或重建二维码。只有内置浏览器明确不可用时,才展示同一个可点击 handoff.url。用户完成后重新运行最初的读取命令,不要再次创建授权请求。",
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
|
+
if (input.agentType?.trim().toLowerCase() === "doubao-work" && platform === "plain_chat") {
|
|
24
|
+
handoff.qr_image_url = input.qrPNGURL ?? vaultQRURL(input.authorizationURL, input.requestID);
|
|
25
|
+
return {
|
|
26
|
+
handoff,
|
|
27
|
+
instruction: "向用户说明这是查看已购内容的只读授权。在当前豆包工作对话中将 handoff.url 标为“直接打开授权页”,将 handoff.qr_image_url 标为“授权二维码图片(保存或用另一台设备扫码)”,然后停止等待。不要解析 URL credential、下载或重建二维码,也不要重复创建授权请求;用户完成后重新运行最初的读取命令。",
|
|
28
|
+
};
|
|
29
|
+
}
|
|
23
30
|
if (platform === "markdown") {
|
|
24
31
|
const downloaded = input.imageAttachEnabled && input.qrPNGURL
|
|
25
32
|
? await downloadBrandQRToTmp(input.qrPNGURL, "auth", input.requestID, {
|
|
@@ -53,6 +60,17 @@ export async function buildVaultHandoff(input) {
|
|
|
53
60
|
...(platform === "terminal" ? { terminalQR: await renderTerminalQR(input.authorizationURL, input.qrFormat ?? "unicode") } : {}),
|
|
54
61
|
};
|
|
55
62
|
}
|
|
63
|
+
function vaultQRURL(authorizationURL, requestID) {
|
|
64
|
+
const url = new URL(authorizationURL);
|
|
65
|
+
const startToken = url.searchParams.get("start_token");
|
|
66
|
+
if (!startToken)
|
|
67
|
+
throw new Error("Backend did not return a usable Vault authorization QR URL");
|
|
68
|
+
url.pathname = `/v1/vault/access-requests/${encodeURIComponent(requestID)}/qr.png`;
|
|
69
|
+
url.search = "";
|
|
70
|
+
url.searchParams.set("start_token", startToken);
|
|
71
|
+
url.hash = "";
|
|
72
|
+
return url.toString();
|
|
73
|
+
}
|
|
56
74
|
function authorizationMarkdown(url, localPath) {
|
|
57
75
|
const lines = ["### ItPay 已购内容授权"];
|
|
58
76
|
if (localPath)
|