@itpay/cli 2.0.36 → 2.0.38

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 (31) hide show
  1. package/README.md +4 -3
  2. package/dist/src/commands/checkout_handoff.js +3 -0
  3. package/dist/src/commands/install.js +2 -0
  4. package/dist/src/commands/readyz.js +1 -1
  5. package/dist/src/commands/services.js +2 -2
  6. package/dist/src/commands/vault_handoff.js +18 -0
  7. package/dist/src/main.js +1 -1
  8. package/dist/src/state/client_context.js +2 -0
  9. package/dist/src/state/config.js +13 -13
  10. package/dist/src/state/device_authority.js +26 -10
  11. package/docs/agent/buyer/identity-and-sessions.json +3 -3
  12. package/docs/agent/buyer/install-and-setup.json +6 -5
  13. package/docs/agent/buyer/quickstart.json +2 -2
  14. package/docs/agent/buyer/render-hosts.json +7 -0
  15. package/docs/cli-reference/agent-types.md +6 -1
  16. package/docs/cli-reference/commands/buy.md +1 -0
  17. package/docs/cli-reference/commands/catalog/list.md +1 -1
  18. package/docs/cli-reference/commands/checkout.md +1 -0
  19. package/docs/cli-reference/commands/device.md +9 -1
  20. package/docs/cli-reference/commands/feedback/submit.md +3 -0
  21. package/docs/cli-reference/commands/install.md +6 -4
  22. package/docs/cli-reference/commands/readyz.md +8 -8
  23. package/docs/cli-reference/commands/services/checkout.md +7 -0
  24. package/docs/cli-reference/commands/services/get.md +1 -1
  25. package/docs/cli-reference/commands/services/next.md +6 -6
  26. package/docs/cli-reference/commands/services/quote.md +2 -2
  27. package/docs/cli-reference/commands/services/start.md +1 -1
  28. package/docs/cli-reference/commands/vault/access.md +5 -1
  29. package/docs/cli-reference/conventions.md +1 -1
  30. package/docs/skill-bundle-rollout/04-first-wave-platforms.md +2 -1
  31. package/package.json +3 -1
package/README.md CHANGED
@@ -25,7 +25,7 @@ Official Agent install prompt(可直接复制给 Agent):
25
25
  Use a separate test prompt to set the exact official Dev Backend. Never put a
26
26
  Dev override in the public install prompt.
27
27
 
28
- 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.
28
+ The CLI defaults to the production Backend `https://app.itpay.ai`. Explicit sandbox runs may set `ITPAY_BACKEND_URL=https://sandbox.itpay.ai`; every other Backend URL is rejected before network or local state access.
29
29
 
30
30
  ## Output Contract
31
31
 
@@ -54,6 +54,7 @@ Normative per-command contracts: [CLI Command Reference](docs/cli-reference/inde
54
54
  | `claude-code-cli` | `terminal` |
55
55
  | `workbuddy` | `plain-chat` |
56
56
  | `zcode` | `plain-chat` |
57
+ | `doubao-work` | `plain-chat` |
57
58
  | `kimi-code` | `terminal` |
58
59
  | `openclaw` | 必须显式提供 |
59
60
 
@@ -90,12 +91,12 @@ itpay --agent-type <agent_type> services checkout <service_execution_id> --resum
90
91
  itpay checkout --id <checkout_id> --token <display_token> --json
91
92
  ```
92
93
 
93
- 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.
94
+ 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`; sandbox uses `cart.sandbox.json` / `operations.sandbox.json`. Backend state remains authoritative. Do not delete or rotate this identity to recover quota.
94
95
 
95
96
  ## Environment
96
97
 
97
98
  - `ITPAY_AGENT_TYPE`: stable alternative to global `--agent-type`.
98
- - `ITPAY_BACKEND_URL`: optional test override; only the exact official URL `https://dev.itpay.ai` is accepted. Unset it for production.
99
+ - `ITPAY_BACKEND_URL`: optional sandbox override; only the exact official URL `https://sandbox.itpay.ai` is accepted. Unset it for production.
99
100
  - `ITPAY_BEARER_TOKEN`: optional account-scoped browser session for legacy account reads. Local Agents normally use signed Device Authority plus the time-limited human authorization returned by `vault access`.
100
101
  - `ITPAY_CART_SESSION_PATH`: local recovery-state path override.
101
102
  - `ITPAY_CURRENCY`: ordinary Cart currency, default `CNY`.
@@ -50,6 +50,9 @@ function checkoutHandoffInstruction(agentType, platform, amount) {
50
50
  if (isZCodePlainChat(agentType, platform)) {
51
51
  return `Backend 尚未确认付款。立即用 ZCode 内置浏览器打开 handoff.url,让用户完成付款;确认已发起打开后说明金额 ${amount},然后停止等待。不要只粘贴文字链接,不要下载、解析或重建二维码,不要创建新 Checkout、Payment Intent 或 Execution。只有内置浏览器明确不可用时,才展示同一个可点击 handoff.url。只有用户明确表示已付款或要求查询状态时,才执行 next.command;用户的话不是付款成功证明。`;
52
52
  }
53
+ if (agentType?.trim().toLowerCase() === "doubao-work" && platform === "plain_chat") {
54
+ return `Backend 尚未确认付款。在当前豆包工作对话中展示两个有标签的官方入口:将 handoff.url 标为“手机直接打开收银台”,将 handoff.qr_image_url 标为“二维码图片(保存或用另一台设备扫码)”。说明金额 ${amount} 后停止等待。不要解析或单独输出 URL credential,不要下载或重建二维码,不要调用 pay,不要创建新 Checkout、Payment Intent 或 Execution。只有用户明确表示已付款或要求查询状态时,才执行 next.command;用户的话不是付款成功证明。`;
55
+ }
53
56
  if (platform === "markdown") {
54
57
  return `Backend 尚未确认付款。把 handoff.markdown 原样发送到当前桌面对话,确认二维码、付款链接和金额 ${amount} 均已实际对用户可见,然后停止等待。不要创建新 Checkout、Payment Intent 或 Execution;只有用户明确表示已付款或要求查询状态时,才执行 next.command;用户的话不是付款成功证明。`;
55
58
  }
@@ -8,6 +8,7 @@ export const INSTALL_AGENT_TYPES = [
8
8
  "claude-code-cli",
9
9
  "workbuddy",
10
10
  "zcode",
11
+ "doubao-work",
11
12
  "kimi-code",
12
13
  "openclaw",
13
14
  ];
@@ -18,6 +19,7 @@ const INSTRUCTIONS = {
18
19
  "claude-code-cli": "在 Claude Code CLI 中始终传这个 Agent Type;付款交接只应显示在用户可见终端。",
19
20
  workbuddy: "在 WorkBuddy 中始终传这个 Agent Type。运行会持久化 ~/.itpay-v3 的 ItPay Bash 命令前,把 Shell 工具参数 dangerouslyDisableSandbox 设为 true;用户拒绝权限时停止,不要切换 Node、删除 identity 或处理 lock。Checkout 返回已渲染的付款 Card Link 和 present_files action;原样执行一次 action 打开 handoff.url,不要检查本地二维码文件。",
20
21
  zcode: "在 ZCode 中始终传这个 Agent Type。Checkout 或授权返回 handoff.url 后,立即用 ZCode 内置浏览器打开;不要只粘贴文字链接或重建二维码。只有内置浏览器不可用时才展示同一个可点击链接。",
22
+ "doubao-work": "在豆包工作中始终传这个 Agent Type。Checkout 或授权返回后,同时展示 handoff.url 和 handoff.qr_image_url 两个有标签的官方入口;优先让用户在手机上直接打开链接,二维码供保存或另一台设备扫码。",
21
23
  "kimi-code": "保持 kimi-code Agent Type,使用标准 CLI 命令和终端付款交接;不要切换到其他平台身份。",
22
24
  openclaw: "保持 openclaw Agent Type;每个展示命令都从当前可信会话上下文显式传 --host,IM 入口同时传 --target。Telegram 使用返回的原生 message action,其他入口展示标准二维码和付款链接。",
23
25
  };
@@ -8,7 +8,7 @@ export async function runReadyz(backend, options = {}) {
8
8
  status: response.status,
9
9
  result: { backend: "available", backend_url: backendURL, environment, ...(options.agentType ? { agent_type: options.agentType } : {}) },
10
10
  instruction: environment === "development"
11
- ? "ItPay dev 可用。先完整读取内置 Skill,再根据用户意图选择新服务、已购内容、订单或退款入口;后续必须执行返回的完整命令并保持同一 dev Backend。"
11
+ ? "ItPay sandbox 可用。先完整读取内置 Skill,再根据用户意图选择新服务、已购内容、订单或退款入口;后续必须执行返回的完整命令并保持同一 sandbox Backend。"
12
12
  : "ItPay 可用。先完整读取内置 Skill,再根据用户意图选择新服务、已购内容、订单或退款入口;不要默认开始购买。",
13
13
  next: { command: "itpay skill show itpay --json", reason: "加载完整操作与安全规则" },
14
14
  recovery: [],
@@ -747,12 +747,12 @@ function servicesNextEnvelope(model) {
747
747
  ? appendFeedbackPostmortemInstruction(items.length > 0
748
748
  ? selection
749
749
  ? "搜索已完成。用编号、名称和可公开字段向用户说明结果,然后停止。只有用户明确选择候选并要求继续时才执行 next.command;不要提及 safe_payload。"
750
- : "这一步的结果已经可用。用普通语言解释可公开字段并停止;不要提及 Graph、safe_payload 或内部 ID。"
750
+ : "这一步的结果已经可用。用普通语言解释可公开字段并停止;不要提及 Arazzo、safe_payload 或内部 ID。"
751
751
  : "告诉用户本次查询得到 0 个结果并停止。Agent 不读取其他交付、不重放当前查询、修改输入或创建新查询。", "delivered")
752
752
  : items.length > 0
753
753
  ? selection
754
754
  ? "搜索已完成。用编号、名称和可公开字段向用户说明结果,然后停止。只有用户明确选择候选并要求继续时才执行 next.command;不要提及 safe_payload。"
755
- : "这一步的结果已经可用。用普通语言解释可公开字段并停止;不要提及 Graph、safe_payload 或内部 ID。"
755
+ : "这一步的结果已经可用。用普通语言解释可公开字段并停止;不要提及 Arazzo、safe_payload 或内部 ID。"
756
756
  : "告诉用户本次查询得到 0 个结果并停止。Agent 不读取其他交付、不重放当前查询、修改输入或创建新查询。",
757
757
  next: selection ? {
758
758
  command: `itpay services action ${execution.service_execution_id} --action select_candidate --actor-type human --status approved --candidate <rank> --json`,
@@ -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)
package/dist/src/main.js CHANGED
@@ -202,7 +202,7 @@ function reportCLIError(error, contract) {
202
202
  ? "临时网络故障;CLI 已仅对可安全重放的操作完成有限自动重试,但仍未获得完整响应。按 recovery 查询同一资源的权威状态;不要创建替代 Checkout、Execution、Payment 或 Refund。"
203
203
  : "网络在完整响应前中断;当前写操作没有安全重放合同,因此 CLI 未自动重试。按 recovery 查询权威状态;不要原样重放或创建替代 Checkout、Execution、Payment 或 Refund。"
204
204
  : backendOverrideError
205
- ? "移除 ITPAY_BACKEND_URL 使用正式环境,或准确设置为 https://dev.itpay.ai。"
205
+ ? "移除 ITPAY_BACKEND_URL 使用正式环境,或准确设置为 https://sandbox.itpay.ai。"
206
206
  : commandError?.instruction ?? authorizationInstruction ?? contract?.instruction ?? "检查命令参数后重试。",
207
207
  next: null,
208
208
  recovery: incompatible
@@ -64,6 +64,8 @@ export function defaultHostForAgentType(agentType) {
64
64
  return "plain-chat";
65
65
  if (normalized === "zcode")
66
66
  return "plain-chat";
67
+ if (normalized === "doubao-work")
68
+ return "plain-chat";
67
69
  if (normalized === "openclaw")
68
70
  return undefined;
69
71
  return "terminal";
@@ -1,5 +1,5 @@
1
1
  // CLI configuration loader. Production defaults to app.itpay.ai; the only
2
- // allowed override is the official dev Backend. Checkout
2
+ // allowed override is the official sandbox 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,9 +11,9 @@ 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 DEV_BASE_URL = "https://dev.itpay.ai";
15
- export const CLI_VERSION = "2.0.36";
16
- export const API_CONTRACT_REVISION = "sha256:20986f3d7a770f9c696c0576f3ae4898f0d23a519bd489c1727382a16270fab2";
14
+ export const SANDBOX_BASE_URL = "https://sandbox.itpay.ai";
15
+ export const CLI_VERSION = "2.0.38";
16
+ export const API_CONTRACT_REVISION = "sha256:06930cb6833e761813d6ad2e260cf0605469234b515402fa25c0c58b9f3c27e9";
17
17
  const CART_SESSION_DEFAULT_DIR = ".itpay-v3";
18
18
  const CART_SESSION_FILENAME = "cart.json";
19
19
  const OPERATION_JOURNAL_FILENAME = "operations.json";
@@ -27,7 +27,7 @@ export function cliDistribution(env = process.env) {
27
27
  export class BackendOverrideError extends Error {
28
28
  code = "backend_override_forbidden";
29
29
  constructor() {
30
- super(`ITPAY_BACKEND_URL only supports ${DEFAULT_BASE_URL} or ${DEV_BASE_URL}`);
30
+ super(`ITPAY_BACKEND_URL only supports ${DEFAULT_BASE_URL} or ${SANDBOX_BASE_URL}`);
31
31
  this.name = "BackendOverrideError";
32
32
  }
33
33
  }
@@ -35,23 +35,23 @@ export function resolveBackendURL(env = process.env) {
35
35
  const requested = env.ITPAY_BACKEND_URL?.trim();
36
36
  if (!requested || requested === DEFAULT_BASE_URL || requested === `${DEFAULT_BASE_URL}/`)
37
37
  return DEFAULT_BASE_URL;
38
- if (requested === DEV_BASE_URL || requested === `${DEV_BASE_URL}/`)
39
- return DEV_BASE_URL;
38
+ if (requested === SANDBOX_BASE_URL || requested === `${SANDBOX_BASE_URL}/`)
39
+ return SANDBOX_BASE_URL;
40
40
  throw new BackendOverrideError();
41
41
  }
42
42
  export function qualifyBackendCommand(command, env = process.env) {
43
43
  const requested = env.ITPAY_BACKEND_URL?.trim();
44
- if (requested !== DEV_BASE_URL && requested !== `${DEV_BASE_URL}/`)
44
+ if (requested !== SANDBOX_BASE_URL && requested !== `${SANDBOX_BASE_URL}/`)
45
45
  return command;
46
- if (!command.startsWith("itpay ") || command.startsWith(`ITPAY_BACKEND_URL=${DEV_BASE_URL} `))
46
+ if (!command.startsWith("itpay ") || command.startsWith(`ITPAY_BACKEND_URL=${SANDBOX_BASE_URL} `))
47
47
  return command;
48
- return `ITPAY_BACKEND_URL=${DEV_BASE_URL} ${command}`;
48
+ return `ITPAY_BACKEND_URL=${SANDBOX_BASE_URL} ${command}`;
49
49
  }
50
50
  function stateFilename(filename, baseURL) {
51
- if (baseURL !== DEV_BASE_URL)
51
+ if (baseURL !== SANDBOX_BASE_URL)
52
52
  return filename;
53
53
  const dot = filename.lastIndexOf(".");
54
- return dot < 0 ? `${filename}.dev` : `${filename.slice(0, dot)}.dev${filename.slice(dot)}`;
54
+ return dot < 0 ? `${filename}.sandbox` : `${filename.slice(0, dot)}.sandbox${filename.slice(dot)}`;
55
55
  }
56
56
  function stateDir(env) {
57
57
  return resolve(env.HOME || homedir(), CART_SESSION_DEFAULT_DIR);
@@ -74,7 +74,7 @@ export function loadConfig(env = process.env) {
74
74
  const ideImageDirOverride = env.ITPAY_IDE_IMAGE_DIR_OVERRIDE;
75
75
  return {
76
76
  baseURL,
77
- environment: baseURL === DEV_BASE_URL ? "development" : "production",
77
+ environment: baseURL === SANDBOX_BASE_URL ? "development" : "production",
78
78
  ...(agentType ? { agentType } : {}),
79
79
  checkoutCurrency,
80
80
  idempotencyKey,
@@ -1,5 +1,5 @@
1
1
  import { createHash, createPrivateKey, createPublicKey, generateKeyPairSync, randomUUID, sign, } from "node:crypto";
2
- import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, rmdirSync, statSync, unlinkSync, writeFileSync, } from "node:fs";
2
+ import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync, } from "node:fs";
3
3
  import { homedir } from "node:os";
4
4
  import { dirname, resolve } from "node:path";
5
5
  const PROTECTED_PATHS = ["/v1/carts", "/v1/service-executions", "/v1/agent-instances", "/v1/orders", "/v1/refunds", "/v1/me", "/v1/vault"];
@@ -292,10 +292,12 @@ async function withFileLock(path, run) {
292
292
  catch (error) {
293
293
  throw asDeviceStatePathError(error, "prepare_lock") ?? error;
294
294
  }
295
+ const ownerToken = randomUUID();
295
296
  let acquired = false;
296
297
  for (let attempt = 0; attempt < 200; attempt += 1) {
297
298
  try {
298
- mkdirSync(path, { mode: 0o700 });
299
+ writeFileSync(path, ownerToken, { encoding: "utf8", flag: "wx", mode: 0o600 });
300
+ chmodSync(path, 0o600);
299
301
  acquired = true;
300
302
  break;
301
303
  }
@@ -305,7 +307,7 @@ async function withFileLock(path, run) {
305
307
  throw asDeviceStateError(error, "acquire_lock") ?? error;
306
308
  try {
307
309
  if (Date.now() - statSync(path).mtimeMs > 30_000)
308
- removeLock(path, "remove_stale_lock");
310
+ moveLockAside(path, "stale", "remove_stale_lock");
309
311
  }
310
312
  catch (statError) {
311
313
  if (statError.code !== "ENOENT") {
@@ -321,19 +323,33 @@ async function withFileLock(path, run) {
321
323
  return await run();
322
324
  }
323
325
  finally {
324
- removeLock(path, "release_lock");
326
+ releaseLock(path, ownerToken);
325
327
  }
326
328
  }
327
- function removeLock(path, operation) {
329
+ function releaseLock(path, ownerToken) {
328
330
  try {
329
- if (statSync(path).isDirectory())
330
- rmdirSync(path);
331
- else
332
- unlinkSync(path);
331
+ if (readFileSync(path, "utf8") !== ownerToken)
332
+ return;
333
+ moveLockAside(path, "released", "release_lock");
333
334
  }
334
335
  catch (error) {
335
336
  if (error.code !== "ENOENT")
336
- throw asDeviceStateError(error, operation) ?? error;
337
+ throw asDeviceStateError(error, "release_lock") ?? error;
338
+ }
339
+ }
340
+ function moveLockAside(path, suffix, operation) {
341
+ try {
342
+ renameSync(path, `${path}.${suffix}`);
343
+ }
344
+ catch (error) {
345
+ const code = error.code;
346
+ if (code === "ENOENT")
347
+ return;
348
+ if (code === "EEXIST" || code === "ENOTEMPTY") {
349
+ renameSync(path, `${path}.${suffix}.${randomUUID()}`);
350
+ return;
351
+ }
352
+ throw asDeviceStateError(error, operation) ?? error;
337
353
  }
338
354
  }
339
355
  function asDeviceStateError(error, operation) {
@@ -12,7 +12,7 @@
12
12
  ],
13
13
  "identity_model": {
14
14
  "local_key": "One owner-only Ed25519 private key for the local installation.",
15
- "backend_registration": "One registration per official Backend: app.itpay.ai by default and dev.itpay.ai only with the exact test override.",
15
+ "backend_registration": "One registration per official Backend: app.itpay.ai by default and sandbox.itpay.ai only with the exact test override.",
16
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
  },
@@ -50,13 +50,13 @@
50
50
  "Use the real runtime type and keep it stable across every command in the flow.",
51
51
  "Keep the same CLI/Node launcher and Host-approved permission context for the whole flow.",
52
52
  "Treat a new window, chat, task, or process of the same runtime as the same Agent Type, not a new identity.",
53
- "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.",
53
+ "Expect production traffic to use https://app.itpay.ai. Use https://sandbox.itpay.ai only for an explicit test and keep the complete returned Backend-prefixed command for that entire flow.",
54
54
  "After automatic recovery fails, stop and report the exact code, selected official Backend, Agent Type, and command family without exposing private keys or tokens."
55
55
  ],
56
56
  "forbidden": [
57
57
  "Do not delete ~/.itpay-v3, rotate the key, switch Agent Type, or repeatedly retry to obtain fresh quota.",
58
58
  "Do not use device recover for session expiry, revocation, quota recovery, or an unconfirmed Backend failure.",
59
- "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.",
59
+ "Do not redirect the CLI to dev, local, an IP, or any custom Backend; only the exact official sandbox.itpay.ai test override is allowed.",
60
60
  "Do not use --target as identity or service input."
61
61
  ],
62
62
  "next_docs": [
@@ -13,7 +13,7 @@
13
13
  {
14
14
  "intent": "list supported Agent Types",
15
15
  "command": "itpay install --json",
16
- "success_signal": "status is install_targets and exactly eight supported Agent Type definitions are returned"
16
+ "success_signal": "status is install_targets and exactly nine supported Agent Type definitions are returned"
17
17
  },
18
18
  {
19
19
  "intent": "read setup for the real runtime",
@@ -35,12 +35,12 @@
35
35
  "Start with install, identify the current real runtime from result.agent_types, run itpay install <agent_type> --json yourself, and then execute each returned next.command unchanged until the Skill is loaded.",
36
36
  "After setup, tell the human only that ItPay is ready; never ask them to run setup commands or explain technical setup steps.",
37
37
  "Use the CLI distribution already provided by the current npm package, Skill, or plugin; update only through that distribution's own instructions.",
38
- "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.",
38
+ "Production defaults to https://app.itpay.ai. Testing may set ITPAY_BACKEND_URL to the exact official URL https://sandbox.itpay.ai; no other Backend is allowed.",
39
39
  "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.",
40
40
  "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.",
41
- "Use one exact type: codex-desktop, codex-cli, claude-code-desktop, claude-code-cli, workbuddy, zcode, kimi-code, or openclaw.",
41
+ "Use one exact type: codex-desktop, codex-cli, claude-code-desktop, claude-code-cli, workbuddy, zcode, doubao-work, kimi-code, or openclaw.",
42
42
  "For compatibility, a global --agent-type codex declaration is normalized immediately to codex-desktop; all registration, output, and returned commands use codex-desktop. Never generate the alias, and do not use codex as an install target.",
43
- "One local private key is reused, while Device registrations and quota lineage remain separate for app.itpay.ai and dev.itpay.ai.",
43
+ "One local private key is reused, while Device registrations and quota lineage remain separate for app.itpay.ai and sandbox.itpay.ai.",
44
44
  "Within each official Backend registration, each Agent Type has one Agent Instance; all windows and chats of the same type reuse it.",
45
45
  "Agent Type identifies the runtime. Host and target only select a presentation destination; load render-hosts only when a handoff cannot be shown.",
46
46
  "Keep the exact Agent Type in every next or recovery command; do not fall back to a type previously used by another runtime.",
@@ -48,7 +48,7 @@
48
48
  ],
49
49
  "forbidden": [
50
50
  "Do not use terminal, claude-code, or plain-chat as Agent Types. Do not generate codex as an Agent Type; it is accepted only as a legacy global declaration and becomes codex-desktop before any request.",
51
- "Do not set or suggest any Backend except the default https://app.itpay.ai or the exact test override https://dev.itpay.ai.",
51
+ "Do not set or suggest any Backend except the default https://app.itpay.ai or the exact test override https://sandbox.itpay.ai.",
52
52
  "Do not claim that install writes host configuration or registers a device; it only prints instructions.",
53
53
  "Do not create a new identity for a different window, task, chat, or process of the same Agent Type."
54
54
  ],
@@ -71,6 +71,7 @@
71
71
  "claude code",
72
72
  "workbuddy",
73
73
  "zcode",
74
+ "doubao work",
74
75
  "kimi code",
75
76
  "openclaw"
76
77
  ]
@@ -12,7 +12,7 @@
12
12
  "required_state": {
13
13
  "needs": [
14
14
  "the real supported Agent Type",
15
- "one official Backend: production https://app.itpay.ai by default, or explicit test https://dev.itpay.ai"
15
+ "one official Backend: production https://app.itpay.ai by default, or explicit test https://sandbox.itpay.ai"
16
16
  ],
17
17
  "must_not_need": [
18
18
  "Admin access",
@@ -38,7 +38,7 @@
38
38
  "Treat result as current facts, instruction as how to use those facts, next as the preferred executable action, and recovery as exceptional paths.",
39
39
  "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.",
40
40
  "Keep the same explicit Agent Type through next and recovery commands; same-type windows reuse one Backend Agent Instance.",
41
- "When testing dev, execute every returned command unchanged so its ITPAY_BACKEND_URL=https://dev.itpay.ai prefix is preserved.",
41
+ "When testing sandbox, execute every returned command unchanged so its ITPAY_BACKEND_URL=https://sandbox.itpay.ai prefix is preserved.",
42
42
  "Use --target only for a Host presentation destination. Put capability business values in --input key=value exactly as required by the schema.",
43
43
  "Start a separate Service Execution for each independent service intent; quota remains shared according to Backend identity policy.",
44
44
  "Ask the user for required email or contact values and explain their purpose; never invent them.",
@@ -40,6 +40,11 @@
40
40
  "default_host": "plain-chat",
41
41
  "responsibility": "open handoff.url immediately in the ZCode built-in browser and stop; only show the same clickable URL when the built-in browser is unavailable"
42
42
  },
43
+ {
44
+ "agent_type": "doubao-work",
45
+ "default_host": "plain-chat",
46
+ "responsibility": "show handoff.url as the preferred same-phone checkout or authorization link and handoff.qr_image_url as the labeled save-or-scan fallback; state the amount for Checkout and stop"
47
+ },
43
48
  {
44
49
  "agent_type": "kimi-code",
45
50
  "default_host": "terminal",
@@ -70,6 +75,7 @@
70
75
  "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.",
71
76
  "For workbuddy with plain-chat, execute handoff.agent_action exactly once; it calls present_files with handoff.url as the only files element and opens the rendered Card Link in the right-side browser.",
72
77
  "For zcode with plain-chat, open handoff.url in the built-in browser. Do not only paste text, download or rebuild a QR, or invent a private browser-tool payload; use the same clickable URL only as fallback.",
78
+ "For doubao-work with plain-chat, show two labeled official links: handoff.url for direct same-phone opening and handoff.qr_image_url for saving or scanning on another device; do not parse credentials, download or rebuild the QR, or create an alternative resource.",
73
79
  "If the WorkBuddy action fails, send the original handoff.url, report that it did not auto-open, and stop without creating another payment resource.",
74
80
  "Do not claim the handoff was shown until both a usable payment image or QR and the Checkout URL are visible.",
75
81
  "IM Hosts that require a target must receive --target before Checkout creation. OpenClaw has no default Host; Kimi Code uses terminal.",
@@ -99,6 +105,7 @@
99
105
  "desktop",
100
106
  "workbuddy",
101
107
  "zcode",
108
+ "doubao work",
102
109
  "kimi code",
103
110
  "openclaw",
104
111
  "telegram"
@@ -16,6 +16,7 @@
16
16
  | `claude-code-cli` | `terminal` | 在用户可见终端输出二维码和官方链接,不声称已在桌面对话展示。 |
17
17
  | `workbuddy` | `plain-chat` | 返回完整渲染的 HTML Card Link 和可原样执行的 `present_files` action;立即打开 Card Link,不返回或检查本地图片路径。 |
18
18
  | `zcode` | `plain-chat` | 返回完整渲染的官方 URL;立即用 ZCode 内置浏览器打开,不只粘贴文字链接,也不返回或重建二维码图片。 |
19
+ | `doubao-work` | `plain-chat` | 同时返回手机直达收银台链接和官方二维码图片链接;在豆包工作对话中明确标注两者,说明金额后停止等待。 |
19
20
  | `kimi-code` | `terminal` | 使用标准 CLI 引导,在用户可见终端渲染二维码和付款链接。 |
20
21
  | `openclaw` | 无;必须显式传入 | `--host telegram` 使用 OpenClaw 原生 `message` action;其他入口返回标准 HTTPS 二维码和付款链接。 |
21
22
 
@@ -34,6 +35,7 @@
34
35
  - OpenClaw 的 IM Host 必须提供 `--target`。缺失时在任何 Checkout 创建前返回 `target_required`。
35
36
  - `kimi-code` 是 CLI 型 Agent,复用 `terminal` Host 和现有 CLI 展示,不增加 Kimi 专属交易协议。
36
37
  - `zcode` 使用 `plain-chat` Host 和官方 URL-only handoff。Agent 必须自行在 ZCode 内置浏览器打开 URL;只有内置浏览器确实不可用时才向用户展示同一个可点击链接。
38
+ - `doubao-work` 使用 `plain-chat` Host。它虽运行在云电脑中,仍走 Local Device Authority;不得改走 MCP 或创建第二套身份。Checkout 和 Vault 授权必须同时展示 `handoff.url` 与 `handoff.qr_image_url`。
37
39
  - session 失效时 CLI 只续期并重试原请求一次;再次失败立即返回。revoked v2 Device 不自动换身份。
38
40
  - 同一 Device 首次登记新的 Agent Type 时,CLI 只使用本地已登记且 Backend 仍接受的既有 Agent Instance 完成签名登记;被撤销的 Instance 会被跳过且不会恢复。若没有任何既有 Instance 可用,CLI 必须停止,不得重新登记 Device、旋转私钥或借用其他 Backend。
39
41
 
@@ -79,6 +81,7 @@ URL 内 credential 不得被提取、单独输出、记录或重建。
79
81
  | `claude-code-cli / terminal` | `url`;非 JSON 输出另外渲染终端二维码 |
80
82
  | `workbuddy / plain-chat` | `url, agent_action`(`present_files(files=[url])`,打开完整渲染的 HTML Card Link) |
81
83
  | `zcode / plain-chat` | `url`(立即用 ZCode 内置浏览器打开;不返回图片或平台私有 action) |
84
+ | `doubao-work / plain-chat` | `url, qr_image_url`(`url` 是本机直接打开的首选入口;`qr_image_url` 是保存或由另一台设备扫码的备用入口) |
82
85
  | `kimi-code / terminal` | `url`;非 JSON 输出另外渲染终端二维码 |
83
86
  | `openclaw / telegram` | `url, qr_image_url, agent_action` |
84
87
  | `openclaw / other` | `url, qr_image_url` |
@@ -87,6 +90,8 @@ WorkBuddy instruction 必须要求 Agent 原样执行一次 `handoff.agent_actio
87
90
 
88
91
  ZCode instruction 必须明确要求 Agent 立即用内置浏览器打开 `handoff.url`,确认已发起打开后说明金额并停止。不得只把 URL 当作文字粘贴给用户,也不得下载、解析或重建二维码。只有内置浏览器明确不可用时,才把同一个 `handoff.url` 作为可点击链接展示。CLI 不猜测或输出 ZCode 私有工具调用 JSON。
89
92
 
93
+ Doubao Work instruction 必须要求 Agent 在当前对话中展示两个有标签的官方入口:优先展示“手机直接打开收银台”对应的 `handoff.url`,再展示“二维码图片(保存或用另一台设备扫码)”对应的 `handoff.qr_image_url`。说明金额后停止等待;不得解析 URL 中的 credential、下载或重建二维码、调用 `pay`,也不得创建替代 Checkout。
94
+
90
95
  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:` 前缀。
91
96
 
92
97
  ### Purchased-content authorization
@@ -94,7 +99,7 @@ OpenClaw Telegram 的 `handoff.agent_action` 是可原样执行的原生 `messag
94
99
  `vault access` 使用相同字段集合,但不包含金额、Checkout ID、付款状态或付款
95
100
  查询命令。桌面 handoff 的 Markdown 标题和链接必须明确为“授权查看已购
96
101
  内容”;Terminal 显示授权二维码;WorkBuddy 用 `present_files` 打开完整
97
- `handoff.url`;ZCode 用内置浏览器打开完整 `handoff.url`;OpenClaw 使用返回的图片/原生 action。
102
+ `handoff.url`;ZCode 用内置浏览器打开完整 `handoff.url`;Doubao Work 同时展示授权链接和官方二维码图片链接;OpenClaw 使用返回的图片/原生 action。
98
103
 
99
104
  授权 handoff 展示后 `next=null`。用户明确表示已完成时,Agent只重新执行
100
105
  产生授权要求的原始 `vault list`、`orders` 或 `vault read`,不得再次执行
@@ -169,6 +169,7 @@ itpay buy \
169
169
  | `claude-code-cli` | `terminal` | `url` | 在用户可见终端展示;不能声称桌面对话已收到图片。 |
170
170
  | `workbuddy` | `plain-chat` | `url,agent_action` | 原样执行一次 `present_files(files=[url])`,在右侧打开完整渲染的 HTML Card Link,然后停止。 |
171
171
  | `zcode` | `plain-chat` | `url` | 立即用 ZCode 内置浏览器打开 URL;只有浏览器不可用时才展示同一个可点击链接。 |
172
+ | `doubao-work` | `plain-chat` | `url,qr_image_url` | 展示“手机直接打开收银台”和“二维码图片(保存或用另一台设备扫码)”两个有标签的官方入口,说明金额后停止。 |
172
173
  | `kimi-code` | `terminal` | `url` | 使用标准 CLI 非 JSON 终端二维码和链接。 |
173
174
  | `openclaw` | 必须显式 | Telegram 返回 `url,qr_image_url,agent_action`;其他入口返回 `url,qr_image_url` | Telegram 执行原生 `message` action;其他入口直接展示图片和链接。 |
174
175
 
@@ -40,7 +40,7 @@ itpay catalog list [--json]
40
40
 
41
41
  ## 异常处理
42
42
 
43
- 输出不得包含 snapshot、manifest 原文、compiled graph 或 Provider secret。服务为空时返回 `catalog_empty`,要求稍后重试,不猜服务 ID。
43
+ 输出不得包含 snapshot、manifest 原文、Arazzo workflow 或 Provider secret。服务为空时返回 `catalog_empty`,要求稍后重试,不猜服务 ID。
44
44
 
45
45
  ## Agent Type / Host
46
46
 
@@ -77,6 +77,7 @@ token 缺失或不匹配时使用本机句柄恢复。只有请求的 Checkout
77
77
  | `claude-code-cli` | `url`;普通文本模式渲染终端二维码。 |
78
78
  | `workbuddy` | 返回 `url,agent_action`;原样执行一次 `present_files(files=[url])` 打开完整渲染的 HTML Card Link,不生成本地文件。 |
79
79
  | `zcode` | 返回 `url`;立即用 ZCode 内置浏览器打开,不只粘贴文字链接,也不生成或重建二维码文件。 |
80
+ | `doubao-work` | 返回 `url,qr_image_url`;展示手机直达收银台链接和官方二维码图片链接,说明金额后停止。 |
80
81
  | `kimi-code` | `url`;普通文本模式渲染标准终端二维码。 |
81
82
  | `openclaw` | Telegram 为 `url,qr_image_url,agent_action`;instruction 强制原样执行 action。`📋 已授权给我读` callback 触发同一 Checkout 查询,再由 Backend 决定是否进入 grant 读取;其他显式 Host 为 `url,qr_image_url`。 |
82
83
 
@@ -12,7 +12,15 @@
12
12
  itpay --agent-type <agent_type> device recover --confirm-backend-reset --json
13
13
  ```
14
14
 
15
- 命令只作用于当前官方 Backend 的 Device registration,并保留本地 Ed25519 私钥、Cart 和业务资源。默认是 `https://app.itpay.ai`;显式测试可使用准确的 `ITPAY_BACKEND_URL=https://dev.itpay.ai`。该命令不访问 Backend、不自动创建新身份;返回的只读 `services list` 会保留同一 Backend,是重新登记入口。
15
+ 命令只作用于当前官方 Backend 的 Device registration,并保留本地 Ed25519 私钥、Cart 和业务资源。默认是 `https://app.itpay.ai`;显式测试可使用准确的 `ITPAY_BACKEND_URL=https://sandbox.itpay.ai`。该命令不访问 Backend、不自动创建新身份;返回的只读 `services list` 会保留同一 Backend,是重新登记入口。
16
+
17
+ 同一台电脑上的多个 Local Agent Type 共享本地 Device key,但各自使用独立 Agent
18
+ Instance。CLI 只在原子更新 Device state 时使用短期本地锁;释放和 stale recovery
19
+ 通过 rename 完成,不依赖 Host 删除文件,因此 WorkBuddy 等 sandbox 的
20
+ safe-delete/trash shim 不应阻断正常命令。该锁不在 Backend,不会让另一台电脑或
21
+ 另一个 Buyer 等待。遇到本地锁错误时不得删除 `~/.itpay-v3/device`、切换 Agent
22
+ Type 或执行 `device recover`;应保留身份并重试原命令一次,持续失败时报告
23
+ `device_state_unwritable` 或 lock timeout。
16
24
 
17
25
  缺少确认参数返回 `backend_reset_confirmation_required`。普通 session 失效由 CLI 自动续期;revoked、quota、权限或未知 Backend 故障不得使用本命令。所有 Agent Type 使用相同输入和输出合同。
18
26
 
@@ -73,6 +73,9 @@ Markdown:
73
73
 
74
74
  没有用户评论时省略 Summary,但仍保存 Context。只写用户明确内容和已知安全上下文;禁止 Token、Session、联系方式、内部身份、
75
75
  Provider 响应、Vault payload、完整命令输出、stack trace 或环境变量。
76
+ CLI 不读取或上传 Host 对话、WorkBuddy/ZCode sandbox 日志或其他本地 Agent
77
+ 记录。用户自愿提供本地证据时,Agent 也只能提炼与本单有关的安全摘要,不能把原始
78
+ 日志作为 Feedback note 上传。
76
79
 
77
80
  ## 成功 JSON
78
81
 
@@ -18,10 +18,10 @@ itpay install [target] [--json]
18
18
 
19
19
  | 参数 | 必填 | 说明 |
20
20
  | --- | --- | --- |
21
- | `target` | 否 | 八种正式 Agent Type 之一;省略或传 `list` 时列出全部。Host 名称不是合法 target。 |
21
+ | `target` | 否 | 九种正式 Agent Type 之一;省略或传 `list` 时列出全部。Host 名称不是合法 target。 |
22
22
  | `--json` | 否 | 返回标准命令 envelope;推荐 Agent 使用。 |
23
23
 
24
- 正式 target:`codex-desktop`、`codex-cli`、`claude-code-desktop`、`claude-code-cli`、`workbuddy`、`zcode`、`kimi-code`、`openclaw`。
24
+ 正式 target:`codex-desktop`、`codex-cli`、`claude-code-desktop`、`claude-code-cli`、`workbuddy`、`zcode`、`doubao-work`、`kimi-code`、`openclaw`。
25
25
 
26
26
  ## 指定 Agent Type 输出
27
27
 
@@ -77,7 +77,7 @@ OpenClaw 额外明确没有默认入口:
77
77
 
78
78
  ## 列表输出
79
79
 
80
- 省略 target 或传 `list` 时返回八组运行时定义,不重复每种类型的完整 instruction:
80
+ 省略 target 或传 `list` 时返回九组运行时定义,不重复每种类型的完整 instruction:
81
81
 
82
82
  ```json
83
83
  {
@@ -90,6 +90,7 @@ OpenClaw 额外明确没有默认入口:
90
90
  { "agent_type": "claude-code-cli", "default_host": "terminal" },
91
91
  { "agent_type": "workbuddy", "default_host": "plain-chat" },
92
92
  { "agent_type": "zcode", "default_host": "plain-chat" },
93
+ { "agent_type": "doubao-work", "default_host": "plain-chat" },
93
94
  { "agent_type": "kimi-code", "default_host": "terminal" },
94
95
  {
95
96
  "agent_type": "openclaw",
@@ -122,6 +123,7 @@ OpenClaw 额外明确没有默认入口:
122
123
  | `claude-code-cli` | `terminal` | 只在用户可见终端展示付款交接。 |
123
124
  | `workbuddy` | `plain-chat` | 会持久化 `~/.itpay-v3` 的 Bash 调用先设 Shell 工具参数 `dangerouslyDisableSandbox=true`;拒绝权限时停止。Checkout 原样执行返回的 `present_files` action,打开渲染后的 Card Link。 |
124
125
  | `zcode` | `plain-chat` | Checkout 或授权返回后立即用 ZCode 内置浏览器打开 `handoff.url`;只有浏览器不可用时才展示同一个可点击链接。 |
126
+ | `doubao-work` | `plain-chat` | Checkout 或授权时同时展示 `handoff.url` 和 `handoff.qr_image_url` 两个有标签的官方入口;优先让手机直接打开链接,二维码供保存或另一台设备扫码。 |
125
127
  | `kimi-code` | `terminal` | 使用标准 CLI 流程和终端展示,不增加 Kimi 专属命令。 |
126
128
  | `openclaw` | 无 | 必须显式提供当前入口;Telegram 使用原生 action,其他入口展示标准二维码和链接。 |
127
129
 
@@ -140,7 +142,7 @@ OpenClaw 额外明确没有默认入口:
140
142
  "code": "unsupported_agent_type",
141
143
  "message": "unsupported install target: codex"
142
144
  },
143
- "instruction": "target 只接受:codex-desktop, codex-cli, claude-code-desktop, claude-code-cli, workbuddy, zcode, kimi-code, openclaw。",
145
+ "instruction": "target 只接受:codex-desktop, codex-cli, claude-code-desktop, claude-code-cli, workbuddy, zcode, doubao-work, kimi-code, openclaw。",
144
146
  "next": null,
145
147
  "recovery": [
146
148
  {
@@ -4,9 +4,9 @@
4
4
 
5
5
  ## 范围与意义
6
6
 
7
- 检查当前官方 Backend 是否可用。默认使用生产环境 `https://app.itpay.ai`;仅测试时可通过 `ITPAY_BACKEND_URL=https://dev.itpay.ai` 选择官方开发环境。它只调用 `/v1/readyz` 做 liveness 诊断,不执行平台兼容性 gate、不登记设备、不创建业务资源;需要服务端合同的命令仍会在各自入口严格检查 compatibility。
7
+ 检查当前官方 Backend 是否可用。默认使用生产环境 `https://app.itpay.ai`;仅测试时可通过 `ITPAY_BACKEND_URL=https://sandbox.itpay.ai` 选择官方沙箱环境。它只调用 `/v1/readyz` 做 liveness 诊断,不执行平台兼容性 gate、不登记设备、不创建业务资源;需要服务端合同的命令仍会在各自入口严格检查 compatibility。
8
8
 
9
- **上游:** CLI 安装;Backend 只能是官方 `https://app.itpay.ai` 或 `https://dev.itpay.ai`,其他 override 在网络或本地状态写入前被拒绝。
9
+ **上游:** CLI 安装;Backend 只能是官方 `https://app.itpay.ai` 或 `https://sandbox.itpay.ai`,其他 override 在网络或本地状态写入前被拒绝。
10
10
  **下游:** 完整 `itpay` Skill;由 Agent 根据用户意图选择新服务、已购内容、订单或退款入口。
11
11
 
12
12
  ## 语法与参数
@@ -31,14 +31,14 @@ itpay readyz [--json]
31
31
  }
32
32
  ```
33
33
 
34
- 开发环境返回同一 envelope,但明确标记环境并在每个后续命令中保留 dev Backend:
34
+ 沙箱环境返回同一 envelope,但明确标记环境并在每个后续命令中保留 sandbox Backend:
35
35
 
36
36
  ```json
37
37
  {
38
38
  "status": "ready",
39
- "result": { "backend": "available", "backend_url": "https://dev.itpay.ai", "environment": "development" },
40
- "instruction": "ItPay dev 可用。先完整读取内置 Skill,再根据用户意图选择新服务、已购内容、订单或退款入口;后续必须执行返回的完整命令并保持同一 dev Backend。",
41
- "next": { "command": "ITPAY_BACKEND_URL=https://dev.itpay.ai itpay skill show itpay --json", "reason": "加载完整操作与安全规则" },
39
+ "result": { "backend": "available", "backend_url": "https://sandbox.itpay.ai", "environment": "development" },
40
+ "instruction": "ItPay sandbox 可用。先完整读取内置 Skill,再根据用户意图选择新服务、已购内容、订单或退款入口;后续必须执行返回的完整命令并保持同一 sandbox Backend。",
41
+ "next": { "command": "ITPAY_BACKEND_URL=https://sandbox.itpay.ai itpay skill show itpay --json", "reason": "加载完整操作与安全规则" },
42
42
  "recovery": []
43
43
  }
44
44
  ```
@@ -54,9 +54,9 @@ itpay readyz [--json]
54
54
  "status": "error",
55
55
  "error": {
56
56
  "code": "backend_override_forbidden",
57
- "message": "ITPAY_BACKEND_URL only supports https://app.itpay.ai or https://dev.itpay.ai"
57
+ "message": "ITPAY_BACKEND_URL only supports https://app.itpay.ai or https://sandbox.itpay.ai"
58
58
  },
59
- "instruction": "移除 ITPAY_BACKEND_URL 使用正式环境,或准确设置为 https://dev.itpay.ai。",
59
+ "instruction": "移除 ITPAY_BACKEND_URL 使用正式环境,或准确设置为 https://sandbox.itpay.ai。",
60
60
  "next": null,
61
61
  "recovery": []
62
62
  }
@@ -84,6 +84,7 @@ itpay services checkout <service_execution_id> --resume
84
84
  | `claude-code-cli` | `handoff={url}`;普通文本模式在用户可见终端渲染二维码。 |
85
85
  | `workbuddy` | `handoff={url,agent_action}`;原样执行一次 `present_files(files=[url])` 打开完整渲染的 HTML Card Link,然后停止;不得检查或生成本地文件。 |
86
86
  | `zcode` | `handoff={url}`;立即用 ZCode 内置浏览器打开,然后停止;只有浏览器不可用时才展示同一个可点击链接。 |
87
+ | `doubao-work` | `handoff={url,qr_image_url}`;在当前对话中展示手机直达收银台链接和官方二维码图片链接,说明金额后停止。 |
87
88
  | `kimi-code` | `handoff={url}`;复用标准 CLI 终端展示。 |
88
89
  | `openclaw` | 必须显式传 Host;Telegram 还必须传 OpenClaw 原生 Target,并返回必须原样执行的 `message` action;其他入口返回标准 `url,qr_image_url`。 |
89
90
 
@@ -99,6 +100,12 @@ ZCode 的准确 instruction 语义必须完整包含:
99
100
  Backend 尚未确认付款。立即用 ZCode 内置浏览器打开 handoff.url,让用户完成付款;确认已发起打开后说明金额,然后停止等待。不要只粘贴文字链接,不要下载、解析或重建二维码,不要创建新 Checkout、Payment Intent 或 Execution。只有内置浏览器明确不可用时,才展示同一个可点击 handoff.url。只有用户明确表示已付款或要求查询状态时,才执行 next.command;用户的话不是付款成功证明。
100
101
  ```
101
102
 
103
+ Doubao Work 的准确 instruction 语义必须完整包含:
104
+
105
+ ```text
106
+ Backend 尚未确认付款。在当前豆包工作对话中展示两个有标签的官方入口:将 handoff.url 标为“手机直接打开收银台”,将 handoff.qr_image_url 标为“二维码图片(保存或用另一台设备扫码)”。说明金额后停止等待。不要解析或单独输出 URL credential,不要下载或重建二维码,不要调用 pay,不要创建新 Checkout、Payment Intent 或 Execution。只有用户明确表示已付款或要求查询状态时,才执行 next.command;用户的话不是付款成功证明。
107
+ ```
108
+
102
109
  `--locale` 默认 `zh-CN`,可显式使用 `--locale en`。语言只影响 Card 渲染,不改变 Checkout、付款或恢复状态。
103
110
 
104
111
  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` 前不得读取结果。
@@ -59,7 +59,7 @@ itpay services get <service_execution_id> [--json]
59
59
 
60
60
  ## 异常处理
61
61
 
62
- 默认不返回原始 events、Provider metadata、内部 bindings、graph projection、capability schema、candidate hash、client context 或完整 payload。需要完整但仍经服务端脱敏的事件时才运行 `services events`。
62
+ 默认不返回原始 events、Provider metadata、内部 bindings、Arazzo workflow、capability schema、candidate hash、client context 或完整 payload。需要完整但仍经服务端脱敏的事件时才运行 `services events`。
63
63
 
64
64
  execution 不存在或不属于当前身份时保留不透明 `not_found`,只恢复到 `itpay services list --json`;不得通过错误差异探测其他账号。
65
65
 
@@ -7,9 +7,9 @@
7
7
  读取一笔 Service Execution 的当前状态,并只返回一个首选下一步。若交付模式允许 Agent 直接读取,本命令同时返回完整 safe result。
8
8
 
9
9
  **上游:** `services start`、`invoke`、`action`、`checkout`,或一次中断恢复。
10
- **下游:** 一个可执行命令、需要用户完成的候选选择或授权,或 Graph 真正到达终态。
10
+ **下游:** 一个可执行命令、需要用户完成的候选选择或授权,或 Arazzo workflow 真正到达终态。
11
11
 
12
- 本命令不返回原始 Backend DTO、capability 列表、内部 result ID/hash、graph、binding 或重复 guidance。
12
+ 本命令不返回原始 Backend DTO、capability 列表、内部 result ID/hash、Arazzo workflow、binding 或重复 guidance。
13
13
 
14
14
  Backend 会根据当前 capability 选择 `current_delivery`;完整 `delivery_bindings` 仅是历史记录。CLI 不按数组位置猜测当前交付,同一 Execution 后续产生的新交付会取代旧交付成为默认结果。
15
15
 
@@ -28,7 +28,7 @@ itpay services next <service_execution_id> [--json]
28
28
 
29
29
  ## 候选选择
30
30
 
31
- 免费或付费候选已经产生、Graph 允许继续选择时,恢复输出必须包含当前 Result Set 的安全候选:
31
+ 免费或付费候选已经产生、Arazzo workflow 允许继续选择时,恢复输出必须包含当前 Result Set 的安全候选:
32
32
 
33
33
  ```json
34
34
  {
@@ -76,7 +76,7 @@ itpay services next <service_execution_id> [--json]
76
76
  }
77
77
  ```
78
78
 
79
- 只有 Graph 允许继续选择时才返回上述 `next`。若结果本身就是最终交付,instruction 要求用普通语言解释可公开字段并停止,且 `next: null`。文本输出可以保留 Agent 执行所需的 Execution 与 `delivery_mode`,但 Agent 不向用户暴露这些内部词、Result Item ID、Invocation ID 或 Hash。
79
+ 只有 Arazzo workflow 允许继续选择时才返回上述 `next`。若结果本身就是最终交付,instruction 要求用普通语言解释可公开字段并停止,且 `next: null`。文本输出可以保留 Agent 执行所需的 Execution 与 `delivery_mode`,但 Agent 不向用户暴露这些内部词、Result Item ID、Invocation ID 或 Hash。
80
80
 
81
81
  ## Vault 交付
82
82
 
@@ -91,7 +91,7 @@ itpay services next <service_execution_id> [--json]
91
91
  "delivery_mode": "vault_artifact",
92
92
  "grant_status": "none"
93
93
  },
94
- "instruction": "这是当前 Graph 步骤对应的交付;请用户在订单页面授权,未授权前不要读取或猜测内容。",
94
+ "instruction": "这是当前 Arazzo step 对应的交付;请用户在订单页面授权,未授权前不要读取或猜测内容。",
95
95
  "next": {
96
96
  "command": "itpay services read-result <id> --json",
97
97
  "reason": "仅在用户确认授权后执行"
@@ -141,7 +141,7 @@ itpay services next <service_execution_id> [--json]
141
141
  "grant_status": "active",
142
142
  "grant_expires_at": "<RFC3339 time>"
143
143
  },
144
- "instruction": "这是当前 Graph 步骤对应的交付;用户授权有效,立即读取并遵守字段范围与到期时间。",
144
+ "instruction": "这是当前 Arazzo step 对应的交付;用户授权有效,立即读取并遵守字段范围与到期时间。",
145
145
  "next": {
146
146
  "command": "itpay services read-result <id> --json",
147
147
  "reason": "读取当前有效 grant 的结果"
@@ -8,7 +8,7 @@
8
8
 
9
9
  本命令是多 Execution 合并付款的高级入口。普通单 Execution 流程应使用 `services checkout`,不要把 `services quote` 当作 Checkout 失败后的替代路径。
10
10
 
11
- **上游:** 用户明确要求合并多个独立 Execution,且每个 Execution 的 Graph 当前都允许 `prepare_quote`。
11
+ **上游:** 用户明确要求合并多个独立 Execution,且每个 Execution 的 Arazzo workflow 当前都允许 `prepare_quote`。
12
12
 
13
13
  **下游:** `cart add --quote`。多个独立 Execution 的 Quote 可以加入同一 Cart。
14
14
 
@@ -57,7 +57,7 @@ itpay services quote <service_execution_id> --capability <capability_id>
57
57
  - `capability_input_invalid`:缺少 required input;不创建 Quote、Cart 或 Checkout。
58
58
  - `delivery_email_required`:先说明邮箱用于交付 claim link,再询问用户;禁止代填。
59
59
  - 候选未确认、来自其他 Execution、Quote 已存在冲突:Backend 拒绝且不改变 Execution。
60
- - `service_quote_not_allowed`:当前 Graph 不允许从当前 Execution 状态购买该 capability;不得换 capability、新建 Execution 或尝试其他购买命令,只回到同一 Execution 的 `services next`。
60
+ - `service_quote_not_allowed`:当前 Arazzo workflow 不允许从当前 Execution 状态购买该 capability;不得换 capability、新建 Execution 或尝试其他购买命令,只回到同一 Execution 的 `services next`。
61
61
  - Backend 不支持当前交易合同时返回 `backend_contract_incompatible`,必须停止,不能改用 `services checkout`、`cart`、`buy` 或 `pay` 绕过。
62
62
 
63
63
  ## Agent Type / Host
@@ -44,7 +44,7 @@ itpay --agent-type <agent_type> services start <service_id>
44
44
  }
45
45
  ```
46
46
 
47
- Start API 只提供免费额度上限,不提供当前剩余额度,因此本命令不得虚构 `remaining`。不得输出全部 capability DTO、contract version、graph ID、buyer/device ID 或重复 guidance。若服务不存在,recovery 为 `catalog list`。设备 session 由 CLI 自动登记或刷新;401 `agent_device_session_required` 仅续期并重试一次,仍失败时返回错误,不循环。
47
+ Start API 只提供免费额度上限,不提供当前剩余额度,因此本命令不得虚构 `remaining`。不得输出全部 capability DTO、contract version、Arazzo workflow、buyer/device ID 或重复 guidance。若服务不存在,recovery 为 `catalog list`。设备 session 由 CLI 自动登记或刷新;401 `agent_device_session_required` 仅续期并重试一次,仍失败时返回错误,不循环。
48
48
 
49
49
  ## Agent Type / Host
50
50
 
@@ -27,7 +27,8 @@ itpay vault access [--artifact <artifact_ref>] [--host <host>] [--target <target
27
27
  "handoff": {
28
28
  "url": "https://app.itpay.ai/vault/access/...",
29
29
  "qr_local_path": "<desktop-optional-local-path>",
30
- "markdown": "<desktop-optional-host-ready-markdown>"
30
+ "markdown": "<desktop-optional-host-ready-markdown>",
31
+ "qr_image_url": "<chat-host-optional-absolute-https-png>"
31
32
  },
32
33
  "instruction": "说明这是当前智能体的只读授权,实际展示 handoff,然后停止;用户完成后重新运行最初的读取命令。",
33
34
  "next": null,
@@ -53,6 +54,7 @@ Agent不得提取、单独输出、记录或重建其中的 credential;但不
53
54
  | `claude-code-cli / terminal` | `url`;文本模式同时渲染终端二维码 |
54
55
  | `workbuddy / plain-chat` | `url, agent_action` |
55
56
  | `zcode / plain-chat` | `url`;立即用内置浏览器打开,浏览器不可用时才展示可点击链接 |
57
+ | `doubao-work / plain-chat` | `url, qr_image_url`;展示“直接打开授权页”和“授权二维码图片(保存或用另一台设备扫码)”两个有标签的官方入口 |
56
58
  | `kimi-code / terminal` | `url`;文本模式同时渲染终端二维码 |
57
59
  | `openclaw / telegram` | `url, qr_image_url, agent_action` |
58
60
  | `openclaw / other` | `url, qr_image_url` |
@@ -61,3 +63,5 @@ Agent不得提取、单独输出、记录或重建其中的 credential;但不
61
63
  未显示并发送同一个 URL;不得创建替代请求。
62
64
 
63
65
  ZCode 不接收图片路径或二维码 URL。instruction 必须要求 Agent立即用内置浏览器打开完整 `handoff.url`,然后停止等待;不得只粘贴文字链接或重建二维码。仅当内置浏览器明确不可用时才展示同一个可点击链接。
66
+
67
+ Doubao Work 的两个字段都是必需项。若兼容 Backend 未直接返回二维码 URL,CLI 必须从同一官方授权入口派生 Backend 的对应二维码端点;无法安全派生时命令必须明确失败,不得返回缺字段的 handoff。instruction 必须要求 Agent 同时展示完整 `handoff.url` 与 `handoff.qr_image_url`,清楚区分直接打开与跨设备扫码用途,然后停止等待。不得解析 credential、下载或重建二维码,也不得重复执行 `vault access` 检查状态。
@@ -37,7 +37,7 @@ CLI 输出是给 Agent 执行的协议,不是后端 DTO 的调试转储。默
37
37
  - `recovery`:成功时通常为空;失败或中断时最多两个动作。
38
38
  - 一旦命令声明 `--agent-type` 或 `ITPAY_AGENT_TYPE`,所有 ItPay `next.command` 和 `recovery.command` 都保留同一类型。
39
39
  - 相同事实不得同时出现在顶层、`agent_guidance`、`next_actions` 等多个位置。
40
- - 默认隐藏 buyer、device、contract version、compiled graph、quote lock、内部 event ID 等实现细节。
40
+ - 默认隐藏 buyer、device、contract version、Arazzo workflow、quote lock、内部 event ID 等实现细节。
41
41
  - token、付款 URL 和本地二维码路径只在确实需要交给用户时返回,并不得写入日志型命令。
42
42
 
43
43
  ## 默认文本输出
@@ -12,6 +12,7 @@
12
12
  | --- | --- | --- | --- | --- | --- | --- | --- |
13
13
  | ChatGPT + Codex | `itpay-plugin-chatgpt` | ChatGPT MCP;本地 Codex CLI | OpenAI app-plus-skills plugin、MCP config、Skill、离线 CLI | blocked:Buyer Vault 候选尚未完成外部发布 | 2026-08-10 automated CI;ChatGPT/Codex 真机待验收 | pre-Vault `2b1e8a9c8030` | 当前 MCP 合同、OAuth refresh/revoke、OpenAI 审核;本地 CLI bundle pin |
14
14
  | WorkBuddy | `itpay-skill-workbuddy` | 本地 CLI;显式 MCP | SkillHub/local Skill 包、单文件 CLI、MCP OAuth | blocked:Buyer Vault 候选尚未同步 SkillHub | 2026-08-10 automated CI;WorkBuddy 真机待验收 | pre-Vault `584ebf3f8c46` | 权限模式、窄浏览器、OAuth 回跳/refresh、SkillHub 状态 |
15
+ | 豆包工作 | `itpay-ai/cli` | 云电脑内的本地 CLI | 官方 npm CLI;`doubao-work` Agent Type | candidate:CLI 合同与自动化测试完成后待豆包工作真机验收 | 待本轮 automated CI 与真机验收 | 发布前 CLI tag | 云电脑安装/持久化、本机直达链接、二维码备用链接 |
15
16
  | OpenClaw / ClawHub | `itpay-skill-openclaw` | host-dependent CLI | ClawHub Skill、单文件 CLI | blocked:Buyer Vault 候选尚未同步 ClawHub | 2026-08-10 automated CI;OpenClaw 真机待验收 | pre-Vault `af2aa79d85c8` | 公开目录/审核状态、host renderer、更新/回滚 |
16
17
  | Kimi Work / Kimi Code | `itpay-plugin-kimi-work` | Work MCP;Code host-dependent CLI | Kimi plugin + Skill、离线 CLI | blocked:Buyer Vault 候选尚未发布;公开 release 仍为 `v2.0.17` | 2026-08-10 automated CI;两个 surface 真机待验收 | `v2.0.17` / `b8d40fe9cffd` | 两个 surface 真机、MCP Token persistence、市场状态 |
17
18
  | Hermes Agent / Skills Hub | `itpay-skill-hermes` | host-dependent CLI | GitHub Skill tap、单文件 CLI | blocked:Buyer Vault 候选尚未同步 Skills Hub | 2026-08-10 automated CI;Hermes 真机待验收 | pre-Vault `1189f25103fd` | Skills Hub/trusted 状态、更新/回滚、可选 MCP 真机 |
@@ -29,7 +30,7 @@ the named platform has real acceptance and its distribution surface is updated.
29
30
  | --- | --- | --- |
30
31
  | Claude / Claude Code | planned | 确认分发面和仓库,完成 manifest、CLI/MCP 路由、OAuth/Device 真机验收。 |
31
32
  | Gemini CLI | planned | 确认当前 Extension 规则,完成仓库、manifest、bundle 和真机验收。 |
32
- | 豆包/扣子/火山/其他 | unconfirmed | 明确具体产品面和官方第三方发布入口,不能相互代替。 |
33
+ | 扣子/火山/其他 | unconfirmed | 明确具体产品面和官方第三方发布入口,不能相互代替。 |
33
34
 
34
35
  不要创建空仓库占位,也不要根据旧建议名单宣称支持。
35
36
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itpay/cli",
3
- "version": "2.0.36",
3
+ "version": "2.0.38",
4
4
  "description": "The ItPay CLI for services, orders, and human-authorized purchased content.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -31,6 +31,8 @@
31
31
  "codex",
32
32
  "openclaw",
33
33
  "zcode",
34
+ "doubao-work",
35
+ "doubao",
34
36
  "trae"
35
37
  ],
36
38
  "license": "MIT",