@itpay/cli 2.1.2 → 2.1.4

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.
@@ -408,7 +408,7 @@ export async function runServicesCheckout(backend, config, serviceExecutionID, c
408
408
  if (missingInput.length > 0 && !readModel.workflow_entry && readModel.execution.next_action !== "create_checkout") {
409
409
  throw new CommandContractError("capability_input_invalid", `missing required capability input: ${missingInput.join(", ")}`, "补齐付费 capability 的 required_input;本次没有创建 quote、Checkout 或订单。", [{ command: checkoutCommand(serviceExecutionID, capability, lockedInput), reason: "提交完整且会被锁定的服务输入" }]);
410
410
  }
411
- if (capability.delivery_email_required && String(deliveryContact.email ?? "").trim() === "") {
411
+ if (capability.delivery_email_required && readModel.workflow_entry?.capability_id !== capability.capability_id && String(deliveryContact.email ?? "").trim() === "") {
412
412
  throw new CommandContractError("delivery_email_required", "delivery email is required before creating this service checkout", "该 capability 的交付链接会发送到用户邮箱;先向用户说明用途并询问邮箱,不要代填。", [{
413
413
  command: `itpay services checkout ${serviceExecutionID} --capability ${capability.capability_id}${formatInputOptions(lockedInput)} --email <email> --json`,
414
414
  reason: "使用用户提供的邮箱创建 Checkout",
@@ -500,14 +500,14 @@ export async function runServicesQuote(backend, serviceExecutionID, capabilityID
500
500
  const selectionBacked = model.execution.status === "human_action_approved" &&
501
501
  model.allowed_actions?.some((action) => action.type === "prepare_quote" && action.capability_id === capabilityID);
502
502
  const missingInput = missingRequiredInput(capability.input_schema, input);
503
- if (missingInput.length > 0 && !selectionBacked) {
503
+ if (missingInput.length > 0 && !selectionBacked && model.workflow_entry?.capability_id !== capability.capability_id) {
504
504
  throw new CommandContractError("capability_input_invalid", `missing required capability input: ${missingInput.join(", ")}`, "补齐付费 capability 输入;本次没有创建 Quote、Cart 或 Checkout。", [{ command: quoteCommand(serviceExecutionID, capability, input), reason: "提交完整且会被锁定的输入" }]);
505
505
  }
506
506
  const deliveryContact = {
507
507
  ...(options.deliveryContact ?? {}),
508
508
  ...(options.email ? { email: options.email } : {}),
509
509
  };
510
- if (capability.delivery_email_required && String(deliveryContact.email ?? "").trim() === "") {
510
+ if (capability.delivery_email_required && model.workflow_entry?.capability_id !== capability.capability_id && String(deliveryContact.email ?? "").trim() === "") {
511
511
  throw new CommandContractError("delivery_email_required", "delivery email is required before preparing this service quote", "交付链接会发送到用户邮箱;说明用途并询问邮箱,不要代填。", [{ command: quoteCommand(serviceExecutionID, capability, input), reason: "使用用户提供的邮箱创建报价" }]);
512
512
  }
513
513
  const quote = await backend.prepareServiceQuote(serviceExecutionID, {
@@ -559,6 +559,8 @@ export async function runServicesGet(backend, serviceExecutionID, options = {})
559
559
  ...(execution.current_capability_id ? { current_capability_id: execution.current_capability_id } : {}),
560
560
  updated_at: execution.updated_at,
561
561
  timeline,
562
+ ...(response.workflow ? { workflow: response.workflow } : {}),
563
+ ...(response.rail_booking ? { rail_booking: response.rail_booking } : {}),
562
564
  ...(response.events.length > timeline.length ? { timeline_truncated: true } : {}),
563
565
  ...(deliveryMode ? { delivery_mode: deliveryMode } : {}),
564
566
  ...(lockedRefund ? {
@@ -590,6 +592,8 @@ export async function runServicesGet(backend, serviceExecutionID, options = {})
590
592
  export async function runServicesNext(backend, serviceExecutionID, options = {}) {
591
593
  const response = await backend.getServiceExecution(serviceExecutionID);
592
594
  const envelope = servicesNextEnvelope(response);
595
+ if (response.rail_booking)
596
+ envelope.result = { ...envelope.result, rail_booking: response.rail_booking };
593
597
  writeCommandEnvelope(envelope, {
594
598
  ...(options.jsonOutput !== undefined ? { jsonOutput: options.jsonOutput } : {}),
595
599
  ...(options.output ? { output: options.output } : {}),
@@ -8,7 +8,7 @@ export const SELL_GUIDE = {
8
8
  "Use the authenticated user's existing merchant. KYB and payout changes remain in the dashboard.",
9
9
  "Resolve every API against its declared method, Content-Type, parameters, response schema and locked version. Ask for missing inputs; never guess credentials or change contracts.",
10
10
  "Only saved versions may run. A run is not a saved version. Local evidence cannot grant platform test approval.",
11
- "Public workflows are acyclic, synchronous, per-call; include exactly one payment step and delivery on every success path. Unsupported nodes block publication.",
11
+ "Use the platform node catalog and validator for supported pricing, quotas, confirmation and durable fulfillment. Every paid success path must cross payment and delivery gates.",
12
12
  "Use own credentials for local requests. Platform-managed credentials stay on the platform. Mark execution location honestly.",
13
13
  "Present side effects before live tests. Unknown results stop automatic retries. Local payment/refund/delivery gates are simulated, never real funds.",
14
14
  "Show the exact workflow and version before user confirmation. Preview price, delivery and current terms before explicit submission approval.",
@@ -44,6 +44,8 @@ export const SELL_OPERATIONS = [
44
44
  { command: "pricing get", method: "GET", path: `${draft}/workflow`, scope: read, fields: {}, description: "Read the current price and refund policy" },
45
45
  { command: "pricing set", method: "PUT", path: `${draft}/pricing`, scope: write, fields: { expected_revision: "number", pricing: "object", policy: "object" }, description: "Set per-call price and platform refund policy" },
46
46
  { command: "verify", method: "POST", path: `${draft}/validation-runs`, scope: test, fields: { workflow_version_id: "string", expected_semantic_revision: "number", expected_fixture_revision: "number" }, description: "Start platform verification for an explicitly saved version", confirmation: true },
47
+ { command: "tests start-checkout", method: "POST", path: `${draft}/live-checkout-tests`, scope: test, fields: { expected_revision: "number", agent_instance_id: "string" }, description: "Dev admin only: freeze one success fixture into a private real-checkout test bound to your registered Agent. Payment still requires user confirmation; this does not publish the service.", confirmation: true },
48
+ { command: "tests accept-checkout", method: "POST", path: `${draft}/live-checkout-tests/{execution_id}/accept`, scope: test, fields: {}, description: "Record server-observed issued tickets and completed delivery as evidence for the exact tested revision. Never synthesizes payment or issuance.", confirmation: true },
47
49
  { command: "runs get", method: "GET", path: `${draft}/validation-runs/{run_id}`, scope: read, fields: {}, description: "Inspect platform test nodes and diagnostics" },
48
50
  { command: "runs confirm", method: "POST", path: `${draft}/validation-runs/{run_id}/confirm`, scope: test, fields: { risk_hash: "string" }, description: "Confirm the exact disclosed platform test side effects", confirmation: true },
49
51
  { command: "submission preview", method: "GET", path: `${org}/guide`, scope: read, fields: { draft_id: "string" }, description: "Read publication readiness and required agreements" },
@@ -15,8 +15,8 @@ import { OperationJournal } from "./operation_journal.js";
15
15
  export const DEFAULT_BASE_URL = "https://app.itpay.ai";
16
16
  export const DEV_BASE_URL = "https://dev.itpay.ai";
17
17
  export const SANDBOX_BASE_URL = "https://sandbox.itpay.ai";
18
- export const CLI_VERSION = "2.1.2";
19
- export const API_CONTRACT_REVISION = "sha256:8fc92bcea2b2c5205139382e73295fbabf3ff9b0ae001a7e8d748d3bb6857061";
18
+ export const CLI_VERSION = "2.1.4";
19
+ export const API_CONTRACT_REVISION = "sha256:7f8e09ecee0ab32e3eed3690341fa5bbf6d955dbb464fd79ce0e340667b1085e";
20
20
  const CART_SESSION_DEFAULT_DIR = ".itpay-v3";
21
21
  const CART_SESSION_FILENAME = "cart.json";
22
22
  const OPERATION_JOURNAL_FILENAME = "operations.json";
@@ -1341,3 +1341,24 @@ Options:
1341
1341
  ## Seller login and dev
1342
1342
 
1343
1343
  Use `ITPAY_BACKEND_URL=https://dev.itpay.ai itpay sell auth login` to receive the normal ItPay authorization link. After browser login and required email verification, run `ITPAY_BACKEND_URL=https://dev.itpay.ai itpay sell auth status`. The CLI claims its own account session through the standard API and stores it in an owner-only file; never copy tokens or browser cookies. `itpay sell auth logout` revokes this session. Keep the same backend prefix on subsequent commands; production, dev, and sandbox state are isolated. Agent device enrollment does not grant Seller organization access.
1344
+
1345
+ ## Private dev live checkout acceptance
1346
+
1347
+ `itpay sell tests start-checkout --merchant-id <merchant> --draft-id <draft> --input-json <file> --confirm --json`
1348
+
1349
+ Requires the dev server in live Provider mode, an account-scoped platform admin session,
1350
+ and an active enrolled Agent already bound to the same buyer. The JSON contains
1351
+ `expected_revision` and `agent_instance_id`. Save exactly one success fixture first.
1352
+ This queues a private canary execution; it does not publish a service or pay for a ticket.
1353
+ Disclose the live query side effects before using `--confirm`.
1354
+
1355
+ Resume the returned `service_execution_id` using the normal workflow commands through
1356
+ that Agent. The user confirms the route and submits passenger details in the protected
1357
+ Checkout page. Only a verified payment callback permits supplier creation/payment.
1358
+
1359
+ `itpay sell tests accept-checkout --merchant-id <merchant> --draft-id <draft> --execution-id <execution> --confirm --json`
1360
+
1361
+ Records server-observed completed delivery and issued tickets for the exact frozen
1362
+ workflow, fixture and dependency hashes. Pending, partial, manual-recovery, unpaid or
1363
+ changed tests cannot pass. No payment or issuance assertions are accepted as input.
1364
+ Then use the normal submission and admin review flow; this test alone is not publication.
package/docs/sell.md CHANGED
@@ -61,3 +61,24 @@ Example local MCP configuration (use the existing authenticated CLI account):
61
61
  ## Seller login and dev
62
62
 
63
63
  Use `ITPAY_BACKEND_URL=https://dev.itpay.ai itpay sell auth login` to receive the normal ItPay authorization link. After browser login and required email verification, run `ITPAY_BACKEND_URL=https://dev.itpay.ai itpay sell auth status`. The CLI claims its own account session through the standard API and stores it in an owner-only file; never copy tokens or browser cookies. `itpay sell auth logout` revokes this session. Keep the same backend prefix on subsequent commands; production, dev, and sandbox state are isolated. Agent device enrollment does not grant Seller organization access.
64
+
65
+ ## Private dev live checkout acceptance
66
+
67
+ `itpay sell tests start-checkout --merchant-id <merchant> --draft-id <draft> --input-json <file> --confirm --json`
68
+
69
+ Requires the dev server in live Provider mode, an account-scoped platform admin session,
70
+ and an active enrolled Agent already bound to the same buyer. The JSON contains
71
+ `expected_revision` and `agent_instance_id`. Save exactly one success fixture first.
72
+ This queues a private canary execution; it does not publish a service or pay for a ticket.
73
+ Disclose the live query side effects before using `--confirm`.
74
+
75
+ Resume the returned `service_execution_id` using the normal workflow commands through
76
+ that Agent. The user confirms the route and submits passenger details in the protected
77
+ Checkout page. Only a verified payment callback permits supplier creation/payment.
78
+
79
+ `itpay sell tests accept-checkout --merchant-id <merchant> --draft-id <draft> --execution-id <execution> --confirm --json`
80
+
81
+ Records server-observed completed delivery and issued tickets for the exact frozen
82
+ workflow, fixture and dependency hashes. Pending, partial, manual-recovery, unpaid or
83
+ changed tests cannot pass. No payment or issuance assertions are accepted as input.
84
+ Then use the normal submission and admin review flow; this test alone is not publication.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itpay/cli",
3
- "version": "2.1.2",
3
+ "version": "2.1.4",
4
4
  "description": "The ItPay CLI for services, orders, and human-authorized purchased content.",
5
5
  "type": "module",
6
6
  "bin": {