@itpay/cli 2.0.16 → 2.0.17
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/dist/src/commands/checkout_handoff.js +3 -0
- package/dist/src/render/telegram.js +9 -39
- package/dist/src/state/config.js +1 -1
- package/docs/agent/buyer/render-hosts.json +2 -2
- package/docs/cli-reference/agent-types.md +1 -1
- package/docs/cli-reference/commands/buy.md +1 -1
- package/docs/cli-reference/commands/checkout.md +2 -2
- package/docs/cli-reference/commands/services/checkout.md +2 -2
- package/docs/skill-bundle-rollout/04-first-wave-platforms.md +1 -1
- package/package.json +1 -1
|
@@ -40,5 +40,8 @@ function checkoutHandoffInstruction(agentType, platform, amount, hasQRImage) {
|
|
|
40
40
|
if (platform === "terminal") {
|
|
41
41
|
return `Backend 尚未确认付款。在用户可见终端展示当前 Checkout 的二维码、handoff.url 和金额 ${amount},然后停止等待。不要创建新 Checkout、Payment Intent 或 Execution;只有用户明确表示已付款或要求查询状态时,才执行 next.command;用户的话不是付款成功证明。`;
|
|
42
42
|
}
|
|
43
|
+
if (agentType?.trim().toLowerCase() === "openclaw" && platform === "telegram") {
|
|
44
|
+
return `Backend 尚未确认付款或授权状态。立即使用 OpenClaw 原生 message tool,严格按 handoff.agent_action.tool 和 handoff.agent_action.arguments 原样执行;它会发送金额 ${amount}、二维码、📱 手机点这儿支付和 📋 已授权给我读。不得改写 presentation、换用其他消息工具、拆开按钮发送或用普通回复声称按钮已经发送。确认 message tool 调用成功后停止等待。收到 callback_data "itp:grant_confirmed:<checkout_id>" 时,表示用户声明已在收银台授权读取;立即执行 next.command 查询同一 Checkout,再只执行 Backend 返回的 next.command 进入同一 Execution 的 grant 流程。该 callback 不证明付款成功或 grant 已生效;Backend 未返回 grant_active 前不得读取或猜测结果。若原生 message tool 明确失败或当前 Telegram 未启用 inline buttons,只发送现有 handoff.qr_image_url、金额和 handoff.url,报告按钮不可用并停止;不要创建新的 Checkout、Payment Intent 或 Execution。`;
|
|
45
|
+
}
|
|
43
46
|
return `Backend 尚未确认付款。把 handoff.url 和可用的 handoff.qr_image_url 实际发送到当前会话,说明金额 ${amount},然后停止等待。不要创建新 Checkout、Payment Intent 或 Execution;只有用户明确表示已付款或要求查询状态时,才执行 next.command;用户的话不是付款成功证明。`;
|
|
44
47
|
}
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
// `checkout_qr` (a buyer scans a branded QR from the CLI/agent to
|
|
7
7
|
// land on the human checkout page). We emit the same button shape
|
|
8
8
|
// for all three kinds but adjust the button intent.
|
|
9
|
-
import { ideImageAttachBlock } from "./ide.js";
|
|
10
9
|
function buttonsFor(plan) {
|
|
11
10
|
if (plan.kind === "payment_qr" && plan.paymentIntentID) {
|
|
12
11
|
return [
|
|
@@ -22,23 +21,20 @@ function buttonsFor(plan) {
|
|
|
22
21
|
}
|
|
23
22
|
// checkout_qr
|
|
24
23
|
return [
|
|
25
|
-
{ label: "
|
|
24
|
+
{ label: "📱 手机点这儿支付", kind: "url", url: plan.url },
|
|
26
25
|
...(plan.checkoutID
|
|
27
|
-
? [{ label: "
|
|
26
|
+
? [{ label: "📋 已授权给我读", kind: "callback", intent: "grant_confirmed", ref: plan.checkoutID }]
|
|
28
27
|
: []),
|
|
29
28
|
];
|
|
30
29
|
}
|
|
31
30
|
function nativeButton(button) {
|
|
32
31
|
if (button.kind === "url") {
|
|
33
|
-
return { label: button.label,
|
|
32
|
+
return { label: button.label, url: button.url ?? "" };
|
|
34
33
|
}
|
|
35
34
|
const value = button.intent === "check_checkout_status"
|
|
36
35
|
? `itp:checkout:${button.ref ?? ""}`
|
|
37
36
|
: `itp:${button.intent ?? "callback"}:${button.ref ?? ""}`;
|
|
38
|
-
return { label: button.label,
|
|
39
|
-
}
|
|
40
|
-
function format(plan) {
|
|
41
|
-
return plan.kind === "payment_qr" ? "photo_text_inline_buttons" : "text_inline_buttons";
|
|
37
|
+
return { label: button.label, value };
|
|
42
38
|
}
|
|
43
39
|
export function renderTelegram(plan, options) {
|
|
44
40
|
const out = options.output ?? ((line) => process.stdout.write(line));
|
|
@@ -61,9 +57,8 @@ export function renderTelegram(plan, options) {
|
|
|
61
57
|
"--presentation",
|
|
62
58
|
JSON.stringify(presentation),
|
|
63
59
|
],
|
|
64
|
-
//
|
|
65
|
-
|
|
66
|
-
if_unavailable: "Current agent cannot run `openclaw message send`. Stop and tell the user the native Telegram inline-button tool is missing; do not downgrade to a markdown table or plain link.",
|
|
60
|
+
// Keep the same Checkout visible if native buttons are unavailable.
|
|
61
|
+
if_unavailable: "If `openclaw message send` is unavailable, send the same QR media and Checkout URL as ordinary Telegram content, report that inline buttons are unavailable, and stop. Do not create another Checkout.",
|
|
67
62
|
};
|
|
68
63
|
out(JSON.stringify({ presentation, agent_action: agentAction, openclaw_message: openclawMessage }, null, 2) + "\n");
|
|
69
64
|
}
|
|
@@ -76,40 +71,15 @@ export function buildOpenClawTelegramAction(plan, target) {
|
|
|
76
71
|
? `ItPay auth required — ${plan.summary}`
|
|
77
72
|
: `ItPay checkout QR — ${plan.summary}`;
|
|
78
73
|
const presentation = {
|
|
79
|
-
|
|
80
|
-
media,
|
|
81
|
-
text: message,
|
|
82
|
-
links: plan.platform.links,
|
|
83
|
-
buttons,
|
|
84
|
-
interactions: plan.platform.interactions ?? [],
|
|
85
|
-
blocks: [
|
|
86
|
-
{ type: "text", text: message },
|
|
87
|
-
...(media.length > 0 ? [{ type: "image", url: media[0].url }] : []),
|
|
88
|
-
{ type: "buttons", buttons },
|
|
89
|
-
],
|
|
90
|
-
...(plan.ideImageAttach
|
|
91
|
-
? {
|
|
92
|
-
ide_image_attach: {
|
|
93
|
-
status: plan.ideImageAttach.status,
|
|
94
|
-
local_path: plan.ideImageAttach.localPath,
|
|
95
|
-
mirrors: plan.ideImageAttach.mirrors,
|
|
96
|
-
mime_type: plan.ideImageAttach.mimeType,
|
|
97
|
-
source: plan.ideImageAttach.source,
|
|
98
|
-
...(plan.ideImageAttach.caption ? { caption: plan.ideImageAttach.caption } : {}),
|
|
99
|
-
must_render_reason: plan.ideImageAttach.mustRenderReason,
|
|
100
|
-
...(plan.ideImageAttach.error ? { error: plan.ideImageAttach.error } : {}),
|
|
101
|
-
action: "agent_must_render_into_ide_chat",
|
|
102
|
-
instructions: ideImageAttachBlock(plan.ideImageAttach).filter((line) => line.length > 0),
|
|
103
|
-
},
|
|
104
|
-
}
|
|
105
|
-
: {}),
|
|
74
|
+
blocks: [{ type: "buttons", buttons }],
|
|
106
75
|
};
|
|
76
|
+
const nativeTarget = target.trim().replace(/^telegram:/i, "");
|
|
107
77
|
return {
|
|
108
78
|
tool: "message",
|
|
109
79
|
arguments: {
|
|
110
80
|
action: "send",
|
|
111
81
|
channel: "telegram",
|
|
112
|
-
target,
|
|
82
|
+
target: nativeTarget,
|
|
113
83
|
message,
|
|
114
84
|
...(media[0]?.url ? { media: media[0].url } : {}),
|
|
115
85
|
presentation,
|
package/dist/src/state/config.js
CHANGED
|
@@ -12,7 +12,7 @@ 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
14
|
export const DEV_BASE_URL = "https://dev.itpay.ai";
|
|
15
|
-
export const CLI_VERSION = "2.0.
|
|
15
|
+
export const CLI_VERSION = "2.0.17";
|
|
16
16
|
export const API_CONTRACT_REVISION = "sha256:7f4c40b082292bf823631bcd37d452f4a8537153e30636d5eb3a2b24a77ce602";
|
|
17
17
|
const CART_SESSION_DEFAULT_DIR = ".itpay-v3";
|
|
18
18
|
const CART_SESSION_FILENAME = "cart.json";
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"default_host": null,
|
|
46
46
|
"host_required": true,
|
|
47
47
|
"native_hosts": ["telegram"],
|
|
48
|
-
"responsibility": "pass the
|
|
48
|
+
"responsibility": "pass the native OpenClaw entry target explicitly; for Telegram execute handoff.agent_action unchanged, then treat itp:grant_confirmed callbacks only as permission to query the same Checkout and follow Backend grant state; otherwise show the returned HTTPS QR image and Checkout URL"
|
|
49
49
|
}
|
|
50
50
|
],
|
|
51
51
|
"commands": [
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"For workbuddy with plain-chat, call present_files exactly as the returned instruction says. If it fails, send only handoff.url, report that the preview did not open, and stop.",
|
|
67
67
|
"Do not claim the handoff was shown until both a usable payment image or QR and the Checkout URL are visible.",
|
|
68
68
|
"IM Hosts that require a target must receive --target before Checkout creation. OpenClaw has no default Host; Kimi Code uses terminal.",
|
|
69
|
-
"OpenClaw Telegram
|
|
69
|
+
"OpenClaw Telegram uses flat url/value buttons for deployed-version compatibility. A grant_confirmed callback carries only the Checkout ID, never a display token, and never proves payment or an active grant."
|
|
70
70
|
],
|
|
71
71
|
"forbidden": [
|
|
72
72
|
"Do not expose display tokens separately from the tokenized Checkout handoff.",
|
|
@@ -73,4 +73,4 @@
|
|
|
73
73
|
|
|
74
74
|
WorkBuddy instruction 只在 `handoff.qr_image_url` 存在时要求读取其完整字符串并作为 `files` 数组唯一元素调用 `present_files`。如果该可选字段不存在,必须直接发送 `handoff.url`,明确不要调用 `present_files`。两种情况都要停止等待;不能检查本地文件、下载或重建二维码、调用 `pay` 或创建替代付款资源。显式 `--host` 仍覆盖默认展示方式,因此只有 `workbuddy + plain-chat` 使用该规则。
|
|
75
75
|
|
|
76
|
-
OpenClaw Telegram 的 `handoff.agent_action`
|
|
76
|
+
OpenClaw Telegram 的 `handoff.agent_action` 是可原样执行的原生 `message` tool action。`presentation` 只包含标准 `blocks.buttons`:`📱 手机点这儿支付` 使用扁平 `url`,`📋 已授权给我读` 使用扁平 `value=itp:grant_confirmed:<checkout_id>`;二维码单独使用 action 的 `media`。CLI `instruction` 必须要求 Agent 原样执行该 action,不得改写 Presentation、换用其他消息工具或声称普通文本回复等同于已发送按钮。收到授权 callback 后立即执行 `next.command` 查询同一 Checkout,再只跟随后端返回的同一 Execution grant 流程;callback 只携带 Checkout ID,不携带 display token,也不证明付款或 grant 已生效。OpenClaw `target` 使用原生 chat target(如 `5559456744` 或 `-1001234567890:topic:42`),不添加 `telegram:` 前缀。
|
|
@@ -105,7 +105,7 @@ itpay buy \
|
|
|
105
105
|
|
|
106
106
|
`handoff` 只保留当前 Host 可以使用的字段。不得返回二维码 base64、镜像路径数组、renderer 状态或原始后端 DTO。`agent_action` 只允许出现在 `openclaw + telegram`。
|
|
107
107
|
|
|
108
|
-
**Instruction:** 必须使用下方 Agent Type
|
|
108
|
+
**Instruction:** 必须使用下方 Agent Type 表定义的展示动作;展示完成或失败后停止。OpenClaw Telegram 必须原样执行 `handoff.agent_action`,不得改写 Presentation 或用普通回复冒充按钮已发送。收到 `itp:grant_confirmed:<checkout_id>` 表示用户声明已授权读取,应立即执行 `next.command` 查询同一 Checkout,再只跟随后端 grant 状态;该 callback 本身不证明付款或 grant active。
|
|
109
109
|
|
|
110
110
|
### `--pay` 已观察到付款事件
|
|
111
111
|
|
|
@@ -73,6 +73,6 @@ token 缺失或不匹配时使用本机句柄恢复。只有请求的 Checkout
|
|
|
73
73
|
| `claude-code-cli` | `url`;普通文本模式渲染终端二维码。 |
|
|
74
74
|
| `workbuddy` | `url, qr_image_url?`;有二维码 URL 时按 `services checkout` 相同规则调用 `present_files`,没有时只发送 Checkout URL,不生成本地文件。 |
|
|
75
75
|
| `kimi-code` | `url`;普通文本模式渲染标准终端二维码。 |
|
|
76
|
-
| `openclaw` | Telegram 为 `url,qr_image_url,agent_action
|
|
76
|
+
| `openclaw` | Telegram 为 `url,qr_image_url,agent_action`;instruction 强制原样执行 action。`📋 已授权给我读` callback 触发同一 Checkout 查询,再由 Backend 决定是否进入 grant 读取;其他显式 Host 为 `url,qr_image_url`。 |
|
|
77
77
|
|
|
78
|
-
完成、退款或失效状态下所有 Agent Type 都只返回同一状态和下一步,不渲染二维码。OpenClaw 的 `--target`
|
|
78
|
+
完成、退款或失效状态下所有 Agent Type 都只返回同一状态和下一步,不渲染二维码。OpenClaw 的 `--target` 必须使用原生 chat target 并传入展示层,不能添加 `telegram:` 前缀或被 CLI 参数解析后丢弃。
|
|
@@ -83,7 +83,7 @@ itpay services checkout <service_execution_id> --resume
|
|
|
83
83
|
| `claude-code-cli` | `handoff={url}`;普通文本模式在用户可见终端渲染二维码。 |
|
|
84
84
|
| `workbuddy` | `handoff={url,qr_image_url?}`;有 `qr_image_url` 时读取完整值并作为 `files` 数组唯一元素调用 `present_files`;没有时直接发送金额与 `url`,不得调用 `present_files`。两者随后都停止,不得检查或生成本地文件。 |
|
|
85
85
|
| `kimi-code` | `handoff={url}`;复用标准 CLI 终端展示。 |
|
|
86
|
-
| `openclaw` | 必须显式传 Host;Telegram 还必须传 Target
|
|
86
|
+
| `openclaw` | 必须显式传 Host;Telegram 还必须传 OpenClaw 原生 Target,并返回必须原样执行的 `message` action;其他入口返回标准 `url,qr_image_url`。 |
|
|
87
87
|
|
|
88
88
|
WorkBuddy 的准确 instruction 语义必须完整包含:
|
|
89
89
|
|
|
@@ -93,4 +93,4 @@ Backend 尚未确认付款。读取 handoff.qr_image_url 的完整字符串,
|
|
|
93
93
|
|
|
94
94
|
若 `qr_image_url` 缺失,准确 instruction 必须改为:说明本次没有可展示二维码,发送金额与 `handoff.url`,明确不要调用 `present_files`,然后遵守相同停止和付款证明规则。
|
|
95
95
|
|
|
96
|
-
OpenClaw 的 Host/Target 校验必须发生在读取 execution 后、创建 Checkout 前;校验失败不能调用 Checkout 创建接口。Telegram `agent_action`
|
|
96
|
+
OpenClaw 的 Host/Target 校验必须发生在读取 execution 后、创建 Checkout 前;校验失败不能调用 Checkout 创建接口。Telegram `agent_action.arguments.presentation` 只使用 `blocks.buttons`,其中 `📱 手机点这儿支付` 使用扁平 `url`,`📋 已授权给我读` 使用 `value=itp:grant_confirmed:<checkout_id>`。准确 instruction 必须要求 Agent 立即用原生 `message` tool 原样执行 `handoff.agent_action`,不得改写 Presentation、换工具或用普通回复冒充按钮已发送。收到该 callback 表示用户声明已在收银台授权读取;Agent 立即执行 `next.command` 查询同一 Checkout,再只按 Backend 返回的 `next.command` 进入同一 Execution grant 流程。callback 不包含 display token,也不证明付款或 grant active;Backend 未返回 `grant_active` 前不得读取结果。
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
| --- | --- | --- | --- | --- |
|
|
7
7
|
| ChatGPT + Codex | `itpay-plugin-chatgpt` | OpenAI app-plus-skills plugin | `.codex-plugin/plugin.json`、Skill、离线 CLI、审核测试 | production MCP OAuth、域名 challenge、发布身份、legal/support URLs |
|
|
8
8
|
| WorkBuddy | `itpay-skill-workbuddy` | SkillHub Skill 包 | `SKILL.md`、离线 CLI、权限/数据披露、ZIP | SkillHub 账号内上传由仓库管理员完成 |
|
|
9
|
-
| OpenClaw / ClawHub | `itpay-skill-openclaw` | `@itpay/itpay@2.0.
|
|
9
|
+
| OpenClaw / ClawHub | `itpay-skill-openclaw` | `@itpay/itpay@2.0.17` ClawHub Skill | 已发布单文件 CLI bundle | 首次安全审核与公开目录收录 |
|
|
10
10
|
| Kimi Work / Kimi Code | `itpay-plugin-kimi-work` | `kimi.plugin.json` plugin + Skill | GitHub/Release 安装包、离线 CLI | Kimi Featured/第三方市场提交通道未公开;需桌面版实测 |
|
|
11
11
|
| Hermes Agent / Skills Hub | `itpay-skill-hermes` | GitHub Skill tap | Hermes 专属 Skill、单文件 CLI bundle、自动更新 | Skills Hub 全局默认索引与 trusted 等级需上游收录 |
|
|
12
12
|
| 豆包 | 暂不建仓 | 无可验证的 Skill bundle 发布面 | 保留调研记录 | 公开报道指向 2026-07-15 下线;需确认是否改为扣子、火山方舟 MCP 市场或 TRAE |
|