@itpay/cli 2.0.14 → 2.0.16

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 (56) hide show
  1. package/README.md +5 -4
  2. package/dist/src/commands/buy.js +3 -0
  3. package/dist/src/commands/checkout.js +4 -2
  4. package/dist/src/commands/checkout_handoff.js +7 -0
  5. package/dist/src/commands/compatibility.js +0 -1
  6. package/dist/src/commands/guidance.js +6 -5
  7. package/dist/src/commands/install.js +15 -10
  8. package/dist/src/commands/readyz.js +6 -2
  9. package/dist/src/commands/services.js +14 -6
  10. package/dist/src/main.js +60 -27
  11. package/dist/src/render/telegram.js +51 -25
  12. package/dist/src/state/client_context.js +2 -0
  13. package/dist/src/state/config.js +48 -7
  14. package/docs/agent/buyer/identity-and-sessions.json +10 -10
  15. package/docs/agent/buyer/install-and-setup.json +13 -12
  16. package/docs/agent/buyer/payment-flow.json +1 -0
  17. package/docs/agent/buyer/quickstart.json +4 -2
  18. package/docs/agent/buyer/render-hosts.json +18 -2
  19. package/docs/cli-reference/agent-types.md +12 -2
  20. package/docs/cli-reference/commands/buy.md +9 -4
  21. package/docs/cli-reference/commands/cart/add.md +1 -1
  22. package/docs/cli-reference/commands/cart/clear.md +1 -1
  23. package/docs/cli-reference/commands/cart/index.md +1 -1
  24. package/docs/cli-reference/commands/cart/next.md +1 -1
  25. package/docs/cli-reference/commands/cart/remove.md +2 -2
  26. package/docs/cli-reference/commands/cart/show.md +1 -1
  27. package/docs/cli-reference/commands/catalog/index.md +1 -1
  28. package/docs/cli-reference/commands/checkout.md +5 -3
  29. package/docs/cli-reference/commands/device.md +1 -1
  30. package/docs/cli-reference/commands/docs/index.md +1 -1
  31. package/docs/cli-reference/commands/docs/list.md +1 -1
  32. package/docs/cli-reference/commands/docs/search.md +1 -1
  33. package/docs/cli-reference/commands/docs/show.md +1 -1
  34. package/docs/cli-reference/commands/install.md +46 -12
  35. package/docs/cli-reference/commands/next.md +1 -1
  36. package/docs/cli-reference/commands/readyz.md +61 -10
  37. package/docs/cli-reference/commands/refund/cancel.md +1 -1
  38. package/docs/cli-reference/commands/refund/create.md +1 -1
  39. package/docs/cli-reference/commands/refund/index.md +1 -1
  40. package/docs/cli-reference/commands/refund/list.md +1 -1
  41. package/docs/cli-reference/commands/services/action.md +1 -1
  42. package/docs/cli-reference/commands/services/checkout.md +5 -1
  43. package/docs/cli-reference/commands/services/events.md +1 -1
  44. package/docs/cli-reference/commands/services/get.md +1 -1
  45. package/docs/cli-reference/commands/services/index.md +1 -1
  46. package/docs/cli-reference/commands/services/invoke.md +1 -1
  47. package/docs/cli-reference/commands/services/list.md +1 -1
  48. package/docs/cli-reference/commands/services/read-result.md +1 -1
  49. package/docs/cli-reference/conventions.md +7 -1
  50. package/docs/skill-bundle-rollout/01-mcp-authentication.md +256 -0
  51. package/docs/skill-bundle-rollout/02-platform-bundle-repositories.md +279 -0
  52. package/docs/skill-bundle-rollout/03-platform-publishing.md +271 -0
  53. package/docs/skill-bundle-rollout/04-first-wave-platforms.md +32 -0
  54. package/docs/skill-bundle-rollout/README.md +99 -0
  55. package/package.json +1 -1
  56. package/skills/itpay/SKILL.md +4 -4
@@ -28,14 +28,49 @@ function buttonsFor(plan) {
28
28
  : []),
29
29
  ];
30
30
  }
31
+ function nativeButton(button) {
32
+ if (button.kind === "url") {
33
+ return { label: button.label, action: { type: "url", url: button.url ?? "" } };
34
+ }
35
+ const value = button.intent === "check_checkout_status"
36
+ ? `itp:checkout:${button.ref ?? ""}`
37
+ : `itp:${button.intent ?? "callback"}:${button.ref ?? ""}`;
38
+ return { label: button.label, action: { type: "callback", value } };
39
+ }
31
40
  function format(plan) {
32
41
  return plan.kind === "payment_qr" ? "photo_text_inline_buttons" : "text_inline_buttons";
33
42
  }
34
43
  export function renderTelegram(plan, options) {
35
44
  const out = options.output ?? ((line) => process.stdout.write(line));
36
- const buttons = buttonsFor(plan);
45
+ const agentAction = buildOpenClawTelegramAction(plan, options.target);
46
+ const presentation = agentAction.arguments.presentation;
47
+ const media = collectTelegramMedia(plan);
48
+ const text = agentAction.arguments.message;
49
+ const openclawMessage = {
50
+ command: [
51
+ "openclaw",
52
+ "message",
53
+ "send",
54
+ "--channel",
55
+ "telegram",
56
+ "--target",
57
+ options.target,
58
+ "--message",
59
+ text,
60
+ ...(media.length > 0 ? ["--media", media[0].url] : []),
61
+ "--presentation",
62
+ JSON.stringify(presentation),
63
+ ],
64
+ // Hint: agents that cannot run openclaw must stop and tell the user
65
+ // they lack the native Telegram buttons tool — never downgrade.
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.",
67
+ };
68
+ out(JSON.stringify({ presentation, agent_action: agentAction, openclaw_message: openclawMessage }, null, 2) + "\n");
69
+ }
70
+ export function buildOpenClawTelegramAction(plan, target) {
71
+ const buttons = buttonsFor(plan).map(nativeButton);
37
72
  const media = collectTelegramMedia(plan);
38
- const text = plan.kind === "payment_qr"
73
+ const message = plan.kind === "payment_qr"
39
74
  ? `ItPay payment QR — ${plan.summary}`
40
75
  : plan.kind === "auth_qr"
41
76
  ? `ItPay auth required — ${plan.summary}`
@@ -43,12 +78,12 @@ export function renderTelegram(plan, options) {
43
78
  const presentation = {
44
79
  format: format(plan),
45
80
  media,
46
- text,
81
+ text: message,
47
82
  links: plan.platform.links,
48
83
  buttons,
49
84
  interactions: plan.platform.interactions ?? [],
50
85
  blocks: [
51
- { type: "text", text },
86
+ { type: "text", text: message },
52
87
  ...(media.length > 0 ? [{ type: "image", url: media[0].url }] : []),
53
88
  { type: "buttons", buttons },
54
89
  ],
@@ -64,31 +99,22 @@ export function renderTelegram(plan, options) {
64
99
  must_render_reason: plan.ideImageAttach.mustRenderReason,
65
100
  ...(plan.ideImageAttach.error ? { error: plan.ideImageAttach.error } : {}),
66
101
  action: "agent_must_render_into_ide_chat",
67
- instructions: ideImageAttachBlock(plan.ideImageAttach).filter((l) => l.length > 0),
102
+ instructions: ideImageAttachBlock(plan.ideImageAttach).filter((line) => line.length > 0),
68
103
  },
69
104
  }
70
105
  : {}),
71
106
  };
72
- const openclawMessage = {
73
- command: [
74
- "openclaw",
75
- "message",
76
- "send",
77
- "--channel",
78
- "telegram",
79
- "--target",
80
- options.target,
81
- "--message",
82
- text,
83
- ...(media.length > 0 ? ["--media", media[0].url] : []),
84
- "--presentation",
85
- JSON.stringify(presentation),
86
- ],
87
- // Hint: agents that cannot run openclaw must stop and tell the user
88
- // they lack the native Telegram buttons tool — never downgrade.
89
- 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.",
107
+ return {
108
+ tool: "message",
109
+ arguments: {
110
+ action: "send",
111
+ channel: "telegram",
112
+ target,
113
+ message,
114
+ ...(media[0]?.url ? { media: media[0].url } : {}),
115
+ presentation,
116
+ },
90
117
  };
91
- out(JSON.stringify({ presentation, openclaw_message: openclawMessage }, null, 2) + "\n");
92
118
  }
93
119
  export function renderTelegramInteraction(request, options) {
94
120
  const out = options.output ?? ((line) => process.stdout.write(line));
@@ -97,7 +123,7 @@ export function renderTelegramInteraction(request, options) {
97
123
  mimeType: item.mimeType ?? "image/png",
98
124
  }));
99
125
  const buttons = request.kind === "selector"
100
- ? request.options.map((option) => selectorButton(request.id, option))
126
+ ? request.options.map((option) => nativeButton(selectorButton(request.id, option)))
101
127
  : [];
102
128
  const text = `${request.title} — ${request.prompt}`;
103
129
  const presentation = {
@@ -62,6 +62,8 @@ export function defaultHostForAgentType(agentType) {
62
62
  return "claude-code";
63
63
  if (normalized === "workbuddy")
64
64
  return "plain-chat";
65
+ if (normalized === "openclaw")
66
+ return undefined;
65
67
  return "terminal";
66
68
  }
67
69
  export function validateContext(host, target) {
@@ -1,5 +1,5 @@
1
- // CLI configuration loader. The production Backend is pinned to app.itpay.ai;
2
- // environment variables configure only non-Backend runtime details. Checkout
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,61 @@ 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 CLI_VERSION = "2.0.14";
14
+ export const DEV_BASE_URL = "https://dev.itpay.ai";
15
+ export const CLI_VERSION = "2.0.16";
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 function cliDistribution(env = process.env) {
21
+ if (env.ITPAY_DISTRIBUTION === "openclaw-skill-bundle")
22
+ return "openclaw-skill-bundle";
23
+ if (env.ITPAY_DISTRIBUTION === "kimi-plugin-bundle")
24
+ return "kimi-plugin-bundle";
25
+ return "npm";
26
+ }
27
+ export class BackendOverrideError extends Error {
28
+ code = "backend_override_forbidden";
29
+ constructor() {
30
+ super(`ITPAY_BACKEND_URL only supports ${DEFAULT_BASE_URL} or ${DEV_BASE_URL}`);
31
+ this.name = "BackendOverrideError";
32
+ }
33
+ }
34
+ export function resolveBackendURL(env = process.env) {
35
+ const requested = env.ITPAY_BACKEND_URL?.trim();
36
+ if (!requested || requested === DEFAULT_BASE_URL || requested === `${DEFAULT_BASE_URL}/`)
37
+ return DEFAULT_BASE_URL;
38
+ if (requested === DEV_BASE_URL || requested === `${DEV_BASE_URL}/`)
39
+ return DEV_BASE_URL;
40
+ throw new BackendOverrideError();
41
+ }
42
+ export function qualifyBackendCommand(command, env = process.env) {
43
+ const requested = env.ITPAY_BACKEND_URL?.trim();
44
+ if (requested !== DEV_BASE_URL && requested !== `${DEV_BASE_URL}/`)
45
+ return command;
46
+ if (!command.startsWith("itpay ") || command.startsWith(`ITPAY_BACKEND_URL=${DEV_BASE_URL} `))
47
+ return command;
48
+ return `ITPAY_BACKEND_URL=${DEV_BASE_URL} ${command}`;
49
+ }
50
+ function stateFilename(filename, baseURL) {
51
+ if (baseURL !== DEV_BASE_URL)
52
+ return filename;
53
+ const dot = filename.lastIndexOf(".");
54
+ return dot < 0 ? `${filename}.dev` : `${filename.slice(0, dot)}.dev${filename.slice(dot)}`;
55
+ }
56
+ function stateDir(env) {
57
+ return resolve(env.HOME || homedir(), CART_SESSION_DEFAULT_DIR);
58
+ }
19
59
  export function cartSessionPath(env = process.env) {
20
60
  if (env.ITPAY_CART_SESSION_PATH) {
21
61
  return resolve(env.ITPAY_CART_SESSION_PATH);
22
62
  }
23
- const dir = resolve(homedir(), CART_SESSION_DEFAULT_DIR);
63
+ const dir = stateDir(env);
24
64
  mkdirSync(dir, { recursive: true });
25
- return resolve(dir, CART_SESSION_FILENAME);
65
+ return resolve(dir, stateFilename(CART_SESSION_FILENAME, resolveBackendURL(env)));
26
66
  }
27
67
  export function loadConfig(env = process.env) {
28
- const baseURL = DEFAULT_BASE_URL;
68
+ const baseURL = resolveBackendURL(env);
29
69
  const bearerToken = env.ITPAY_BEARER_TOKEN || undefined;
30
70
  const agentType = declaredAgentType(env);
31
71
  const checkoutCurrency = env.ITPAY_CURRENCY || "CNY";
@@ -34,10 +74,11 @@ export function loadConfig(env = process.env) {
34
74
  const ideImageDirOverride = env.ITPAY_IDE_IMAGE_DIR_OVERRIDE;
35
75
  return {
36
76
  baseURL,
77
+ environment: baseURL === DEV_BASE_URL ? "development" : "production",
37
78
  ...(agentType ? { agentType } : {}),
38
79
  checkoutCurrency,
39
80
  idempotencyKey,
40
- ...(!env.ITPAY_IDEMPOTENCY_KEY ? { operationJournal: new OperationJournal(resolve(homedir(), CART_SESSION_DEFAULT_DIR, OPERATION_JOURNAL_FILENAME)) } : {}),
81
+ ...(!env.ITPAY_IDEMPOTENCY_KEY ? { operationJournal: new OperationJournal(resolve(stateDir(env), stateFilename(OPERATION_JOURNAL_FILENAME, baseURL))) } : {}),
41
82
  ideImageAttach,
42
83
  ...(ideImageDirOverride ? { ideImageDirOverride } : {}),
43
84
  ...(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, the fixed app.itpay.ai production registration, Agent Type instances, and bounded automatic session recovery.",
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 app.itpay.ai Device registration database was reset."
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 production Device registration for https://app.itpay.ai; runtime environment variables cannot redirect the CLI.",
16
- "agent_instance": "One instance per agent_type under the production registration; same-type windows and chats reuse it.",
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 app.itpay.ai is available",
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 app.itpay.ai Device registration database",
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 app.itpay.ai registration is removed and the private key remains"
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 all production CLI traffic to use https://app.itpay.ai; do not set or suggest a Backend URL override.",
52
- "After automatic recovery fails, stop and report the exact code, app.itpay.ai, Agent Type, and command family without exposing private keys or tokens."
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 dev, test, local, or any non-app.itpay.ai Backend.",
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": [
@@ -4,7 +4,7 @@
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": "install-and-setup",
6
6
  "title": "Install And Identify The ItPay Agent Runtime",
7
- "purpose": "Install the CLI, load the complete ItPay Skill, and select one stable Agent Type without confusing identity, Backend, Host, target, or chat window.",
7
+ "purpose": "Load the complete ItPay Skill and select one stable Agent Type without confusing distribution, identity, Backend, Host, target, or chat window.",
8
8
  "when_to_use": [
9
9
  "The CLI is being installed or upgraded.",
10
10
  "The agent needs to confirm its stable runtime identity and default output Host."
@@ -23,7 +23,7 @@
23
23
  {
24
24
  "intent": "list supported Agent Types",
25
25
  "command": "itpay install --json",
26
- "success_signal": "status is install_targets and exactly five agent_type/default_host pairs are returned"
26
+ "success_signal": "status is install_targets and exactly seven supported Agent Type definitions are returned"
27
27
  },
28
28
  {
29
29
  "intent": "read setup for the real runtime",
@@ -32,21 +32,20 @@
32
32
  }
33
33
  ],
34
34
  "agent_rules": [
35
- "Install with npm install -g @itpay/cli.",
36
- "The production Backend is fixed to https://app.itpay.ai and cannot be redirected by runtime environment variables.",
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.",
35
+ "Use the CLI distribution already provided by the current npm package, Skill, or plugin; install only through that distribution's own instructions.",
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
+ "If backend_contract_incompatible includes result.required_cli_version, stop all ItPay business commands and use only the exact distribution-specific update 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
- "Use one exact type: codex-desktop, codex-cli, claude-code-desktop, claude-code-cli, or workbuddy.",
41
- "One local private key is reused with the https://app.itpay.ai production Device registration and quota lineage.",
42
- "Within the production Backend registration, each Agent Type has one Agent Instance; all windows and chats of the same type reuse it.",
43
- "Agent Type identifies the runtime. Host controls rendering and target only identifies a presentation destination.",
39
+ "Use one exact type: codex-desktop, codex-cli, claude-code-desktop, claude-code-cli, workbuddy, kimi-code, or openclaw.",
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.",
42
+ "Agent Type identifies the runtime. Host controls rendering and target only identifies a presentation destination. OpenClaw requires an explicit Host and IM target; Kimi Code uses the standard terminal CLI contract.",
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 a Backend URL override; production CLI traffic always targets https://app.itpay.ai.",
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
  ],
@@ -67,6 +66,8 @@
67
66
  "backend",
68
67
  "codex",
69
68
  "claude code",
70
- "workbuddy"
69
+ "workbuddy",
70
+ "kimi code",
71
+ "openclaw"
71
72
  ]
72
73
  }
@@ -32,6 +32,7 @@
32
32
  "Before creating a single-Service Checkout, send the exact price confirmation requested by the current instruction, stop, and wait for explicit human agreement.",
33
33
  "After presenting a Checkout, stop. Run the returned next.command only after the human completes the payment action or asks to query the same Checkout.",
34
34
  "For workbuddy with plain-chat, present the returned HTTPS QR with present_files exactly as instructed; presentation failure falls back only to handoff.url and never creates another payment resource.",
35
+ "For openclaw with telegram, execute the returned native message action using the current trusted target. For any other explicit OpenClaw Host, show the returned HTTPS QR image and Checkout URL.",
35
36
  "Payment is verified only by Backend Checkout or Order state, never by QR rendering, redirect, or user claim.",
36
37
  "A terminal payment state must never display another payment handoff."
37
38
  ],
@@ -12,7 +12,7 @@
12
12
  "required_state": {
13
13
  "needs": [
14
14
  "the real supported Agent Type",
15
- "the fixed production Backend https://app.itpay.ai"
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 fixed production Backend availability",
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,7 +57,9 @@
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.",
62
+ "OpenClaw must pass the current entry as --host and an IM destination as --target. Kimi Code follows the standard terminal CLI flow.",
61
63
  "Start a separate Service Execution for each independent service intent; quota remains shared according to Backend identity policy.",
62
64
  "Ask the user for required email or contact values and explain their purpose; never invent them.",
63
65
  "Agent-visible delivery is returned by services next. Protected delivery is read only by services read-result while a human grant is active.",
@@ -34,6 +34,18 @@
34
34
  "agent_type": "workbuddy",
35
35
  "default_host": "plain-chat",
36
36
  "responsibility": "when handoff.qr_image_url exists, use its exact HTTPS value as the only files element in present_files; otherwise send the Checkout URL without calling present_files; show the amount and stop"
37
+ },
38
+ {
39
+ "agent_type": "kimi-code",
40
+ "default_host": "terminal",
41
+ "responsibility": "use the standard CLI terminal QR and Checkout URL"
42
+ },
43
+ {
44
+ "agent_type": "openclaw",
45
+ "default_host": null,
46
+ "host_required": true,
47
+ "native_hosts": ["telegram"],
48
+ "responsibility": "pass the current entry explicitly; for Telegram execute handoff.agent_action with the current target, otherwise show the returned HTTPS QR image and Checkout URL"
37
49
  }
38
50
  ],
39
51
  "commands": [
@@ -53,7 +65,8 @@
53
65
  "A local QR path is not visible until a desktop Agent attaches or renders that file on the human-facing surface; WorkBuddy never receives a local QR path.",
54
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.",
55
67
  "Do not claim the handoff was shown until both a usable payment image or QR and the Checkout URL are visible.",
56
- "IM Hosts that require a target must receive --target; the initial five Agent Types currently default to desktop, terminal, or plain-chat Hosts."
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 typed callback actions carry only the Checkout ID, never a display token, and never prove payment."
57
70
  ],
58
71
  "forbidden": [
59
72
  "Do not expose display tokens separately from the tokenized Checkout handoff.",
@@ -74,6 +87,9 @@
74
87
  "markdown",
75
88
  "terminal",
76
89
  "desktop",
77
- "workbuddy"
90
+ "workbuddy",
91
+ "kimi code",
92
+ "openclaw",
93
+ "telegram"
78
94
  ]
79
95
  }
@@ -15,6 +15,8 @@
15
15
  | `claude-code-desktop` | `claude-code` | 返回桌面对话可展示的 Markdown 图片和付款链接,要求先展示再等待。 |
16
16
  | `claude-code-cli` | `terminal` | 在用户可见终端输出二维码和链接,不声称已在桌面对话展示。 |
17
17
  | `workbuddy` | `plain-chat` | 只返回 HTTPS 二维码和付款链接;要求 Agent 用 `present_files` 在右侧预览打开二维码,不返回或检查本地图片路径。 |
18
+ | `kimi-code` | `terminal` | 使用标准 CLI 引导,在用户可见终端渲染二维码和付款链接。 |
19
+ | `openclaw` | 无;必须显式传入 | `--host telegram` 使用 OpenClaw 原生 `message` action;其他入口返回标准 HTTPS 二维码和付款链接。 |
18
20
 
19
21
  ## 通用规则
20
22
 
@@ -24,8 +26,11 @@
24
26
  - 显式 `--host` 覆盖默认 Host,但不改变已登记的 Agent Type。
25
27
  - `--target` 只路由人类展示,不是身份,也不是 capability 业务输入。
26
28
  - Host 只影响 `instruction` 和 `handoff`,不得改变金额、订单、权限、quota 或交付状态。
27
- - 五种 Agent Type 使用同一命令输入和 JSON 外壳;不得为单个 Agent Type 新增、删除或改名协议字段。
28
- - 非展示命令在五种 Agent Type 下返回相同业务结果,只允许 `instruction` 措辞不同。只有 Host 客观无法展示某种媒介时,`handoff` 才按既有可选字段做最小裁剪。
29
+ - 七种 Agent Type 使用同一命令输入和 JSON 外壳;OpenClaw 只在 `handoff` 的既有扩展位置增加平台 action,不改变交易字段。
30
+ - 非展示命令在七种 Agent Type 下返回相同业务结果,只允许 `instruction` 措辞不同。只有 Host 客观无法展示某种媒介时,`handoff` 才按既有可选字段做最小裁剪。
31
+ - `openclaw` 没有默认 Host。展示命令必须显式传 `--host`;缺少时在任何 Checkout 创建或状态迁移前返回 `host_required`。
32
+ - OpenClaw 的 IM Host 必须提供 `--target`。缺失时在任何 Checkout 创建前返回 `target_required`。
33
+ - `kimi-code` 是 CLI 型 Agent,复用 `terminal` Host 和现有 CLI 展示,不增加 Kimi 专属交易协议。
29
34
  - session 失效时 CLI 只续期并重试原请求一次;再次失败立即返回。revoked v2 Device 不自动换身份。
30
35
 
31
36
  ## Checkout Handoff 最小合同
@@ -62,5 +67,10 @@
62
67
  | `codex-cli / terminal` | `url`;非 JSON 输出另外渲染终端二维码 |
63
68
  | `claude-code-cli / terminal` | `url`;非 JSON 输出另外渲染终端二维码 |
64
69
  | `workbuddy / plain-chat` | `url, qr_image_url` |
70
+ | `kimi-code / terminal` | `url`;非 JSON 输出另外渲染终端二维码 |
71
+ | `openclaw / telegram` | `url, qr_image_url, agent_action` |
72
+ | `openclaw / other` | `url, qr_image_url` |
65
73
 
66
74
  WorkBuddy instruction 只在 `handoff.qr_image_url` 存在时要求读取其完整字符串并作为 `files` 数组唯一元素调用 `present_files`。如果该可选字段不存在,必须直接发送 `handoff.url`,明确不要调用 `present_files`。两种情况都要停止等待;不能检查本地文件、下载或重建二维码、调用 `pay` 或创建替代付款资源。显式 `--host` 仍覆盖默认展示方式,因此只有 `workbuddy + plain-chat` 使用该规则。
75
+
76
+ OpenClaw Telegram 的 `handoff.agent_action` 使用原生 `message` tool,包含当前 `target`、二维码 media、付款链接和 typed Presentation actions。URL 按钮使用 `action.type=url`;只读查询按钮使用 `action.type=callback`,callback 只携带 Checkout ID,不携带 display token,也不构成付款证明。
@@ -62,8 +62,8 @@ itpay buy \
62
62
  | `--contact-email` | 条件必填 | 普通 Cart 或兼容旧 Quote 缺少所需邮箱时使用,值必须来自用户;新版 Service Quote 会自动携带已确认邮箱。 |
63
63
  | `--contact-phone` | 条件必填 | `--require-contact` 包含 `phone` 时必填,值必须来自用户。 |
64
64
  | `--require-contact` | 否 | 只接受 `email`、`phone`;缺失时先询问用户,禁止 Agent 编造。 |
65
- | `--host` | | 默认由 `--agent-type` 推导;只改变 handoff 展示,不改变交易事实。 |
66
- | `--target` | 条件必填 | 只有要求目标会话的 IM Host 才需要;当前首批五种 Agent Type 无需提供。 |
65
+ | `--host` | 条件必填 | 通常由 `--agent-type` 推导;`openclaw` 必须显式传当前入口。只改变 handoff 展示,不改变交易事实。 |
66
+ | `--target` | 条件必填 | 要求目标会话的 IM Host 必须提供;OpenClaw 从当前可信会话上下文传入。 |
67
67
  | `--qr-format` | 否 | 非 JSON 的终端渲染选项。 |
68
68
  | `--qr-file` | 否 | 非 JSON handoff 的明确二维码文件路径。 |
69
69
  | `--pay` | 否 | 创建 Payment Intent 的集成/运维入口;普通 Agent 流程只展示 Checkout。 |
@@ -91,7 +91,8 @@ itpay buy \
91
91
  "url": "<tokenized_checkout_url>",
92
92
  "qr_local_path": "<desktop_optional_host_ready_file>",
93
93
  "markdown": "<desktop_only_optional_markdown>",
94
- "qr_image_url": "<workbuddy_only_absolute_https_png>"
94
+ "qr_image_url": "<chat_host_optional_absolute_https_png>",
95
+ "agent_action": "<openclaw_telegram_only_native_message_action>"
95
96
  },
96
97
  "instruction": "<current_host_instruction>",
97
98
  "next": {
@@ -102,7 +103,7 @@ itpay buy \
102
103
  }
103
104
  ```
104
105
 
105
- `handoff` 只保留当前 Host 可以使用的字段。不得返回二维码 base64、镜像路径数组、renderer 状态、原始后端 DTO 或重复的 `agent_action`。
106
+ `handoff` 只保留当前 Host 可以使用的字段。不得返回二维码 base64、镜像路径数组、renderer 状态或原始后端 DTO。`agent_action` 只允许出现在 `openclaw + telegram`。
106
107
 
107
108
  **Instruction:** 必须使用下方 Agent Type 表定义的展示动作;展示完成或失败后停止。只有用户明确表示已付款或要求查询时才执行 `next.command`,并以后端状态为准。
108
109
 
@@ -165,5 +166,9 @@ itpay buy \
165
166
  | `claude-code-desktop` | `claude-code` | `url`、可用时 `qr_local_path` 和 `markdown` | 把 Markdown handoff 发到当前桌面对话,不能只输出本地路径。 |
166
167
  | `claude-code-cli` | `terminal` | `url` | 在用户可见终端展示;不能声称桌面对话已收到图片。 |
167
168
  | `workbuddy` | `plain-chat` | `url, qr_image_url?` | 有 `qr_image_url` 时调用 `present_files`;没有时只发送金额和 `url` 且不调用工具。两者都停止,不读取本地文件。 |
169
+ | `kimi-code` | `terminal` | `url` | 使用标准 CLI 非 JSON 终端二维码和链接。 |
170
+ | `openclaw` | 必须显式 | Telegram 返回 `url,qr_image_url,agent_action`;其他入口返回 `url,qr_image_url` | Telegram 执行原生 `message` action;其他入口直接展示图片和链接。 |
168
171
 
169
172
  显式 `--host` 可以覆盖展示方式,但不会改变 Agent Type、设备身份、金额、权限或交易状态。
173
+
174
+ OpenClaw 缺少 `--host`,或 IM Host 缺少 `--target` 时,必须在创建 Cart/Checkout 前分别返回 `host_required` 或 `target_required`。
@@ -85,4 +85,4 @@ Quote 模式返回:
85
85
 
86
86
  ## Agent Type / Host
87
87
 
88
- `codex-desktop`、`codex-cli`、`claude-code-desktop`、`claude-code-cli`、`workbuddy` 五种类型都写入真实 Agent Type。默认 Host 分别是 `codex`、`terminal`、`claude-code`、`terminal`、`plain-chat`。业务输出合同相同;此命令本身不显示二维码。
88
+ `codex-desktop`、`codex-cli`、`claude-code-desktop`、`claude-code-cli`、`workbuddy`、`kimi-code`、`openclaw` 七种类型都写入真实 Agent Type。默认 Host 分别是 `codex`、`terminal`、`claude-code`、`terminal`、`plain-chat`。业务输出合同相同;此命令本身不显示二维码。
@@ -52,4 +52,4 @@ itpay cart clear [--local] [--json]
52
52
 
53
53
  ## Agent Type / Host
54
54
 
55
- `codex-desktop`、`codex-cli`、`claude-code-desktop`、`claude-code-cli`、`workbuddy` 五种 Agent Type 行为相同。
55
+ `codex-desktop`、`codex-cli`、`claude-code-desktop`、`claude-code-cli`、`workbuddy`、`kimi-code`、`openclaw` 七种 Agent Type 行为相同。
@@ -29,4 +29,4 @@ itpay cart --help
29
29
 
30
30
  ## Agent Type / Host
31
31
 
32
- Cart 事实在 `codex-desktop`、`codex-cli`、`claude-code-desktop`、`claude-code-cli`、`workbuddy` 五种 Agent Type 下相同;`add` 创建 client context 时记录真实 Agent Type 和 Host。
32
+ Cart 事实在 `codex-desktop`、`codex-cli`、`claude-code-desktop`、`claude-code-cli`、`workbuddy`、`kimi-code`、`openclaw` 七种 Agent Type 下相同;`add` 创建 client context 时记录真实 Agent Type 和 Host。
@@ -70,4 +70,4 @@ itpay buy --cart <cart_id> --json
70
70
 
71
71
  ## Agent Type / Host
72
72
 
73
- `codex-desktop`、`codex-cli`、`claude-code-desktop`、`claude-code-cli`、`workbuddy` 五种 Agent Type 的业务字段、instruction 和 next 相同。本命令不产生二维码或 Host handoff。
73
+ `codex-desktop`、`codex-cli`、`claude-code-desktop`、`claude-code-cli`、`workbuddy`、`kimi-code`、`openclaw` 七种 Agent Type 的业务字段、instruction 和 next 相同。本命令不产生二维码或 Host handoff。
@@ -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;省略时使用固定 `https://app.itpay.ai` 后端下最后保存的 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。 |
@@ -52,4 +52,4 @@ quote/checkout 已锁定时返回 `cart_item_locked`,要求继续已有 Checko
52
52
 
53
53
  ## Agent Type / Host
54
54
 
55
- `codex-desktop`、`codex-cli`、`claude-code-desktop`、`claude-code-cli`、`workbuddy` 五种 Agent Type 行为相同。
55
+ `codex-desktop`、`codex-cli`、`claude-code-desktop`、`claude-code-cli`、`workbuddy`、`kimi-code`、`openclaw` 七种 Agent Type 行为相同。
@@ -64,4 +64,4 @@ canonical 输出不得包含 Catalog variant/offer、line input、Service quote
64
64
 
65
65
  ## Agent Type / Host
66
66
 
67
- `codex-desktop`、`codex-cli`、`claude-code-desktop`、`claude-code-cli`、`workbuddy` 五种 Agent Type 行为相同。
67
+ `codex-desktop`、`codex-cli`、`claude-code-desktop`、`claude-code-cli`、`workbuddy`、`kimi-code`、`openclaw` 七种 Agent Type 行为相同。
@@ -25,4 +25,4 @@ itpay catalog --help
25
25
 
26
26
  ## Agent Type / Host
27
27
 
28
- `codex-desktop`、`codex-cli`、`claude-code-desktop`、`claude-code-cli`、`workbuddy` 五种支持类型的目录事实完全相同。instruction 可按 Agent Type 调整措辞,但不得改变服务排序、价格或可用能力。
28
+ `codex-desktop`、`codex-cli`、`claude-code-desktop`、`claude-code-cli`、`workbuddy`、`kimi-code`、`openclaw` 七种支持类型的目录事实完全相同。instruction 可按 Agent Type 调整措辞,但不得改变服务排序、价格或可用能力。
@@ -18,7 +18,7 @@ itpay checkout [--id <checkout_id>] [--token <display_token>]
18
18
 
19
19
  省略 `--id/--token` 时只能使用本机保存的一组完整句柄;不得把其他 Checkout 的 token 拼接使用。
20
20
 
21
- `--host` 默认由 `--agent-type` 决定。`--target` 为现有 IM Host 兼容参数;当前五种 Agent Type 不需要它。`--json` 输出机器可读合同,不内嵌二维码字符画或图片二进制。
21
+ `--host` 默认由 `--agent-type` 决定;`openclaw` 必须显式传当前入口。IM Host 必须提供 `--target`。`--json` 输出机器可读合同,不内嵌二维码字符画或图片二进制。
22
22
 
23
23
  ## 等待付款输出
24
24
 
@@ -26,7 +26,7 @@ itpay checkout [--id <checkout_id>] [--token <display_token>]
26
26
  {
27
27
  "status": "human_checkout_required",
28
28
  "result": { "checkout_id": "<checkout_id>", "payment": "pending", "amount": "<amount> <currency>" },
29
- "handoff": { "url": "<checkout_url>", "qr_local_path": "<desktop_optional_path>", "qr_image_url": "<workbuddy_optional_absolute_https_png>", "markdown": "<desktop_optional_markdown>" },
29
+ "handoff": { "url": "<checkout_url>", "qr_local_path": "<desktop_optional_path>", "qr_image_url": "<chat_optional_absolute_https_png>", "markdown": "<desktop_optional_markdown>", "agent_action": "<openclaw_telegram_optional_native_message_action>" },
30
30
  "instruction": "<exact_agent_type_instruction>",
31
31
  "next": { "command": "itpay checkout --id <checkout_id> --token <display_token> --json", "reason": "稍后只查询同一 Checkout" },
32
32
  "recovery": []
@@ -72,5 +72,7 @@ token 缺失或不匹配时使用本机句柄恢复。只有请求的 Checkout
72
72
  | `claude-code-desktop` | `url, qr_local_path, markdown`;原样发送 Markdown。 |
73
73
  | `claude-code-cli` | `url`;普通文本模式渲染终端二维码。 |
74
74
  | `workbuddy` | `url, qr_image_url?`;有二维码 URL 时按 `services checkout` 相同规则调用 `present_files`,没有时只发送 Checkout URL,不生成本地文件。 |
75
+ | `kimi-code` | `url`;普通文本模式渲染标准终端二维码。 |
76
+ | `openclaw` | Telegram 为 `url,qr_image_url,agent_action`;其他显式 Host 为 `url,qr_image_url`。 |
75
77
 
76
- 完成、退款或失效状态下五种 Agent Type 都只返回同一状态和下一步,不渲染二维码。
78
+ 完成、退款或失效状态下所有 Agent Type 都只返回同一状态和下一步,不渲染二维码。OpenClaw 的 `--target` 必须传入展示层,不能被 CLI 参数解析后丢弃。
@@ -10,6 +10,6 @@
10
10
  itpay --agent-type <agent_type> device recover --confirm-backend-reset --json
11
11
  ```
12
12
 
13
- 命令只作用于固定生产后端 `https://app.itpay.ai` 的 Device registration,并保留本地 Ed25519 私钥、Cart 和业务资源。CLI 不接受 Backend URL 覆盖。该命令不访问 Backend、不自动创建新身份;返回的只读 `services list` 是重新登记入口。
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 使用相同输入和输出合同。
@@ -27,4 +27,4 @@ itpay docs --help
27
27
 
28
28
  ## Agent Type / Host
29
29
 
30
- `codex-desktop`、`codex-cli`、`claude-code-desktop`、`claude-code-cli`、`workbuddy` 五种 Agent Type 使用同一文档源;topic 内容可以包含各类型专属 section。
30
+ `codex-desktop`、`codex-cli`、`claude-code-desktop`、`claude-code-cli`、`workbuddy`、`kimi-code`、`openclaw` 七种 Agent Type 使用同一文档源;topic 内容可以包含各类型专属 section。
@@ -50,4 +50,4 @@ itpay docs show <topic> --json
50
50
 
51
51
  ## Agent Type / Host
52
52
 
53
- 五种正式 Agent Type 返回相同结果。本命令没有 Host 渲染、设备登记或本地业务状态写入。
53
+ 七种正式 Agent Type 返回相同结果。本命令没有 Host 渲染、设备登记或本地业务状态写入。
@@ -68,4 +68,4 @@ itpay docs search <query> [--json]
68
68
 
69
69
  ## Agent Type / Host
70
70
 
71
- 五种正式 Agent Type 行为相同。本命令不产生 Host handoff。
71
+ 七种正式 Agent Type 行为相同。本命令不产生 Host handoff。
@@ -67,4 +67,4 @@ topic 不存在返回 `doc_not_found`:
67
67
 
68
68
  ## Agent Type / Host
69
69
 
70
- 五种正式 Agent Type 使用同一 topic。topic 若包含多种 Host 指导,Agent 只采用与自身 Agent Type 和当前 Host 匹配的部分。
70
+ 七种正式 Agent Type 使用同一 topic。topic 若包含多种 Host 指导,Agent 只采用与自身 Agent Type 和当前 Host 匹配的部分。