@itpay/cli 2.1.50 → 2.1.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/src/main.js CHANGED
@@ -4453,7 +4453,7 @@ var require_browser = __commonJS({
4453
4453
  var QRCode2 = require_qrcode();
4454
4454
  var CanvasRenderer = require_canvas();
4455
4455
  var SvgRenderer = require_svg_tag();
4456
- function renderCanvas(renderFunc, canvas, text, opts, cb) {
4456
+ function renderCanvas(renderFunc, canvas, text2, opts, cb) {
4457
4457
  const args = [].slice.call(arguments, 1);
4458
4458
  const argsNum = args.length;
4459
4459
  const isLastArgCb = typeof args[argsNum - 1] === "function";
@@ -4465,8 +4465,8 @@ var require_browser = __commonJS({
4465
4465
  throw new Error("Too few arguments provided");
4466
4466
  }
4467
4467
  if (argsNum === 2) {
4468
- cb = text;
4469
- text = canvas;
4468
+ cb = text2;
4469
+ text2 = canvas;
4470
4470
  canvas = opts = void 0;
4471
4471
  } else if (argsNum === 3) {
4472
4472
  if (canvas.getContext && typeof cb === "undefined") {
@@ -4474,8 +4474,8 @@ var require_browser = __commonJS({
4474
4474
  opts = void 0;
4475
4475
  } else {
4476
4476
  cb = opts;
4477
- opts = text;
4478
- text = canvas;
4477
+ opts = text2;
4478
+ text2 = canvas;
4479
4479
  canvas = void 0;
4480
4480
  }
4481
4481
  }
@@ -4484,16 +4484,16 @@ var require_browser = __commonJS({
4484
4484
  throw new Error("Too few arguments provided");
4485
4485
  }
4486
4486
  if (argsNum === 1) {
4487
- text = canvas;
4487
+ text2 = canvas;
4488
4488
  canvas = opts = void 0;
4489
4489
  } else if (argsNum === 2 && !canvas.getContext) {
4490
- opts = text;
4491
- text = canvas;
4490
+ opts = text2;
4491
+ text2 = canvas;
4492
4492
  canvas = void 0;
4493
4493
  }
4494
4494
  return new Promise(function(resolve8, reject) {
4495
4495
  try {
4496
- const data = QRCode2.create(text, opts);
4496
+ const data = QRCode2.create(text2, opts);
4497
4497
  resolve8(renderFunc(data, canvas, opts));
4498
4498
  } catch (e) {
4499
4499
  reject(e);
@@ -4501,7 +4501,7 @@ var require_browser = __commonJS({
4501
4501
  });
4502
4502
  }
4503
4503
  try {
4504
- const data = QRCode2.create(text, opts);
4504
+ const data = QRCode2.create(text2, opts);
4505
4505
  cb(null, renderFunc(data, canvas, opts));
4506
4506
  } catch (e) {
4507
4507
  cb(e);
@@ -4526,8 +4526,8 @@ var require_server = __commonJS({
4526
4526
  var Utf8Renderer = require_utf8();
4527
4527
  var TerminalRenderer = require_terminal2();
4528
4528
  var SvgRenderer = require_svg();
4529
- function checkParams(text, opts, cb) {
4530
- if (typeof text === "undefined") {
4529
+ function checkParams(text2, opts, cb) {
4530
+ if (typeof text2 === "undefined") {
4531
4531
  throw new Error("String required as first argument");
4532
4532
  }
4533
4533
  if (typeof cb === "undefined") {
@@ -4578,11 +4578,11 @@ var require_server = __commonJS({
4578
4578
  }
4579
4579
  }
4580
4580
  __name(getStringRendererFromType, "getStringRendererFromType");
4581
- function render(renderFunc, text, params) {
4581
+ function render(renderFunc, text2, params) {
4582
4582
  if (!params.cb) {
4583
4583
  return new Promise(function(resolve8, reject) {
4584
4584
  try {
4585
- const data = QRCode2.create(text, params.opts);
4585
+ const data = QRCode2.create(text2, params.opts);
4586
4586
  return renderFunc(data, params.opts, function(err, data2) {
4587
4587
  return err ? reject(err) : resolve8(data2);
4588
4588
  });
@@ -4592,7 +4592,7 @@ var require_server = __commonJS({
4592
4592
  });
4593
4593
  }
4594
4594
  try {
4595
- const data = QRCode2.create(text, params.opts);
4595
+ const data = QRCode2.create(text2, params.opts);
4596
4596
  return renderFunc(data, params.opts, params.cb);
4597
4597
  } catch (e) {
4598
4598
  params.cb(e);
@@ -4601,43 +4601,43 @@ var require_server = __commonJS({
4601
4601
  __name(render, "render");
4602
4602
  exports.create = QRCode2.create;
4603
4603
  exports.toCanvas = require_browser().toCanvas;
4604
- exports.toString = /* @__PURE__ */ __name(function toString(text, opts, cb) {
4605
- const params = checkParams(text, opts, cb);
4604
+ exports.toString = /* @__PURE__ */ __name(function toString(text2, opts, cb) {
4605
+ const params = checkParams(text2, opts, cb);
4606
4606
  const type = params.opts ? params.opts.type : void 0;
4607
4607
  const renderer = getStringRendererFromType(type);
4608
- return render(renderer.render, text, params);
4608
+ return render(renderer.render, text2, params);
4609
4609
  }, "toString");
4610
- exports.toDataURL = /* @__PURE__ */ __name(function toDataURL(text, opts, cb) {
4611
- const params = checkParams(text, opts, cb);
4610
+ exports.toDataURL = /* @__PURE__ */ __name(function toDataURL(text2, opts, cb) {
4611
+ const params = checkParams(text2, opts, cb);
4612
4612
  const renderer = getRendererFromType(params.opts.type);
4613
- return render(renderer.renderToDataURL, text, params);
4613
+ return render(renderer.renderToDataURL, text2, params);
4614
4614
  }, "toDataURL");
4615
- exports.toBuffer = /* @__PURE__ */ __name(function toBuffer(text, opts, cb) {
4616
- const params = checkParams(text, opts, cb);
4615
+ exports.toBuffer = /* @__PURE__ */ __name(function toBuffer(text2, opts, cb) {
4616
+ const params = checkParams(text2, opts, cb);
4617
4617
  const renderer = getRendererFromType(params.opts.type);
4618
- return render(renderer.renderToBuffer, text, params);
4618
+ return render(renderer.renderToBuffer, text2, params);
4619
4619
  }, "toBuffer");
4620
- exports.toFile = /* @__PURE__ */ __name(function toFile(path3, text, opts, cb) {
4621
- if (typeof path3 !== "string" || !(typeof text === "string" || typeof text === "object")) {
4620
+ exports.toFile = /* @__PURE__ */ __name(function toFile(path3, text2, opts, cb) {
4621
+ if (typeof path3 !== "string" || !(typeof text2 === "string" || typeof text2 === "object")) {
4622
4622
  throw new Error("Invalid argument");
4623
4623
  }
4624
4624
  if (arguments.length < 3 && !canPromise()) {
4625
4625
  throw new Error("Too few arguments provided");
4626
4626
  }
4627
- const params = checkParams(text, opts, cb);
4627
+ const params = checkParams(text2, opts, cb);
4628
4628
  const type = params.opts.type || getTypeFromFilename(path3);
4629
4629
  const renderer = getRendererFromType(type);
4630
4630
  const renderToFile = renderer.renderToFile.bind(null, path3);
4631
- return render(renderToFile, text, params);
4631
+ return render(renderToFile, text2, params);
4632
4632
  }, "toFile");
4633
- exports.toFileStream = /* @__PURE__ */ __name(function toFileStream(stream, text, opts) {
4633
+ exports.toFileStream = /* @__PURE__ */ __name(function toFileStream(stream, text2, opts) {
4634
4634
  if (arguments.length < 2) {
4635
4635
  throw new Error("Too few arguments provided");
4636
4636
  }
4637
- const params = checkParams(text, opts, stream.emit.bind(stream, "error"));
4637
+ const params = checkParams(text2, opts, stream.emit.bind(stream, "error"));
4638
4638
  const renderer = getRendererFromType("png");
4639
4639
  const renderToFileStream = renderer.renderToFileStream.bind(null, stream);
4640
- render(renderToFileStream, text, params);
4640
+ render(renderToFileStream, text2, params);
4641
4641
  }, "toFileStream");
4642
4642
  }
4643
4643
  });
@@ -7581,7 +7581,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
7581
7581
  * @param {(string | Function)} text - string to add, or a function returning a string
7582
7582
  * @return {Command} `this` command for chaining
7583
7583
  */
7584
- addHelpText(position, text) {
7584
+ addHelpText(position, text2) {
7585
7585
  const allowedValues = ["beforeAll", "before", "after", "afterAll"];
7586
7586
  if (!allowedValues.includes(position)) {
7587
7587
  throw new Error(`Unexpected value for position to addHelpText.
@@ -7590,10 +7590,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
7590
7590
  const helpEvent = `${position}Help`;
7591
7591
  this.on(helpEvent, (context) => {
7592
7592
  let helpStr;
7593
- if (typeof text === "function") {
7594
- helpStr = text({ error: context.error, command: context.command });
7593
+ if (typeof text2 === "function") {
7594
+ helpStr = text2({ error: context.error, command: context.command });
7595
7595
  } else {
7596
- helpStr = text;
7596
+ helpStr = text2;
7597
7597
  }
7598
7598
  if (helpStr) {
7599
7599
  context.write(`${helpStr}
@@ -7673,6 +7673,25 @@ var require_commander = __commonJS({
7673
7673
  }
7674
7674
  });
7675
7675
 
7676
+ // src/services/shared/purchase_contract.generated.ts
7677
+ var purchaseContract = {
7678
+ "version": "itpay.purchase-confirmation.v1",
7679
+ "required": [
7680
+ "review_ref",
7681
+ "request_key",
7682
+ "user_approved",
7683
+ "user_answer",
7684
+ "price_policy"
7685
+ ],
7686
+ "request_key_max_utf16_units": 200,
7687
+ "amount_maximum": 9007199254740991,
7688
+ "modes": {
7689
+ "exact": "amount_minor",
7690
+ "capped": "maximum_minor",
7691
+ "confirm_on_official_page": null
7692
+ }
7693
+ };
7694
+
7676
7695
  // src/client/transport.ts
7677
7696
  var HttpTransportError = class extends Error {
7678
7697
  constructor(code, attempts, causeCode, cause) {
@@ -7879,7 +7898,7 @@ var HttpClient = class _HttpClient {
7879
7898
  if (options.bearer) headers.Authorization = `Bearer ${options.bearer}`;
7880
7899
  if (options.idempotencyKey) headers["Idempotency-Key"] = options.idempotencyKey;
7881
7900
  let response;
7882
- let text;
7901
+ let text2;
7883
7902
  try {
7884
7903
  response = await this.fetchImpl(url, {
7885
7904
  method,
@@ -7894,7 +7913,7 @@ var HttpClient = class _HttpClient {
7894
7913
  requestID = headerID;
7895
7914
  diagnostic.request_id = headerID;
7896
7915
  }
7897
- text = await response.text();
7916
+ text2 = await response.text();
7898
7917
  this.localSimulation = response.headers.get("X-ItPay-Environment") === "local_simulation";
7899
7918
  } catch (error2) {
7900
7919
  if (options.signal?.aborted) {
@@ -7912,7 +7931,7 @@ var HttpClient = class _HttpClient {
7912
7931
  throw asTransientTransportError(error2, transportRetries + 1) ?? error2;
7913
7932
  }
7914
7933
  record(response.ok ? void 0 : `HTTP_${response.status}`);
7915
- const parsed = text.length > 0 ? safeParseJson(text) : void 0;
7934
+ const parsed = text2.length > 0 ? safeParseJson(text2) : void 0;
7916
7935
  if (response.ok) return parsed;
7917
7936
  const error = new HttpError(response.status, parsed, `HTTP ${response.status}`);
7918
7937
  if (!authorizationRecovered && error.status === 401 && error.code === "agent_device_session_required" && this.recoverAuthorization) {
@@ -7956,9 +7975,9 @@ function safeRouteTemplate(path3) {
7956
7975
  return path3.split("/").map((segment) => staticSegments.has(segment) ? segment : segment ? "{value}" : "").join("/");
7957
7976
  }
7958
7977
  __name(safeRouteTemplate, "safeRouteTemplate");
7959
- function safeParseJson(text) {
7978
+ function safeParseJson(text2) {
7960
7979
  try {
7961
- return JSON.parse(text);
7980
+ return JSON.parse(text2);
7962
7981
  } catch {
7963
7982
  return void 0;
7964
7983
  }
@@ -8232,10 +8251,10 @@ async function streamSSE(url, onEvent, signal) {
8232
8251
  signal
8233
8252
  });
8234
8253
  if (!response.ok) {
8235
- const text = await response.text();
8254
+ const text2 = await response.text();
8236
8255
  let msg = `SSE stream failed: HTTP ${response.status}`;
8237
8256
  try {
8238
- const parsed = JSON.parse(text);
8257
+ const parsed = JSON.parse(text2);
8239
8258
  msg = parsed.message || parsed.code || msg;
8240
8259
  } catch {
8241
8260
  }
@@ -8373,9 +8392,9 @@ function readRegular(path3) {
8373
8392
  }
8374
8393
  }
8375
8394
  __name(readRegular, "readRegular");
8376
- function writeComplete(path3, text, createOnly) {
8395
+ function writeComplete(path3, text2, createOnly) {
8377
8396
  const temp = `${path3}.${randomUUID2()}.tmp`;
8378
- writeFileSync2(temp, text, { flag: "wx", mode: 384 });
8397
+ writeFileSync2(temp, text2, { flag: "wx", mode: 384 });
8379
8398
  try {
8380
8399
  if (createOnly) {
8381
8400
  try {
@@ -8452,12 +8471,12 @@ var DeviceSessionCache = class {
8452
8471
  }
8453
8472
  read() {
8454
8473
  const before = this.generation(false);
8455
- const text = readRegular(this.cachePath);
8456
- if (text === void 0) return void 0;
8474
+ const text2 = readRegular(this.cachePath);
8475
+ if (text2 === void 0) return void 0;
8457
8476
  if (before === void 0) throw invalid2("DEVICE_CACHE_GENERATION_MISSING");
8458
8477
  let record;
8459
8478
  try {
8460
- record = JSON.parse(text);
8479
+ record = JSON.parse(text2);
8461
8480
  } catch {
8462
8481
  throw invalid2("DEVICE_CACHE_CORRUPT");
8463
8482
  }
@@ -8470,11 +8489,11 @@ var DeviceSessionCache = class {
8470
8489
  }
8471
8490
  registrationHint() {
8472
8491
  this.checkDirectory();
8473
- const text = readRegular(this.cachePath);
8474
- if (text === void 0) return void 0;
8492
+ const text2 = readRegular(this.cachePath);
8493
+ if (text2 === void 0) return void 0;
8475
8494
  let record;
8476
8495
  try {
8477
- record = JSON.parse(text);
8496
+ record = JSON.parse(text2);
8478
8497
  } catch {
8479
8498
  throw invalid2("DEVICE_CACHE_CORRUPT");
8480
8499
  }
@@ -8502,9 +8521,9 @@ function deviceCacheAgentTypes(directory, backend, keyThumbprint) {
8502
8521
  }
8503
8522
  const types = /* @__PURE__ */ new Set();
8504
8523
  for (const file of files.filter((name) => /^[0-9a-f]{64}\.(json|generation)$/.test(name))) {
8505
- const text = readRegular(join(directory, file));
8506
- if (text === void 0) continue;
8507
- const value = JSON.parse(text);
8524
+ const text2 = readRegular(join(directory, file));
8525
+ if (text2 === void 0) continue;
8526
+ const value = JSON.parse(text2);
8508
8527
  if (value?.backend !== backend || value?.keyThumbprint !== keyThumbprint) continue;
8509
8528
  const marker = file.endsWith(".generation");
8510
8529
  if (value.schemaVersion !== (marker ? "itpay.device-generation.v1" : "itpay.device-session.v1")) throw invalid2("DEVICE_CACHE_CORRUPT");
@@ -9042,7 +9061,10 @@ __name(isOperationID, "isOperationID");
9042
9061
  // src/state/config.ts
9043
9062
  var DEFAULT_BASE_URL = "https://app.itpay.ai";
9044
9063
  var DEV_BASE_URL = "https://dev.itpay.ai";
9064
+ var V4_DEV_BASE_URL = "https://v4-dev.itpay.ai";
9045
9065
  var SANDBOX_BASE_URL = "https://sandbox.itpay.ai";
9066
+ var TEST_BASE_URL = "https://app-test.itpay.ai";
9067
+ var OFFICIAL_BACKEND_URLS = [DEFAULT_BASE_URL, SANDBOX_BASE_URL, DEV_BASE_URL, TEST_BASE_URL, V4_DEV_BASE_URL];
9046
9068
  var CART_SESSION_DEFAULT_DIR = ".itpay-v3";
9047
9069
  var CART_SESSION_FILENAME = "cart.json";
9048
9070
  var OPERATION_JOURNAL_FILENAME = "operations.json";
@@ -9059,15 +9081,15 @@ var BackendOverrideError = class extends Error {
9059
9081
  }
9060
9082
  code = "backend_override_forbidden";
9061
9083
  constructor() {
9062
- super(`ITPAY_BACKEND_URL only supports ${DEFAULT_BASE_URL}, ${SANDBOX_BASE_URL}, or ${DEV_BASE_URL}`);
9084
+ super(`ITPAY_BACKEND_URL only supports ${OFFICIAL_BACKEND_URLS.join(", ")}`);
9063
9085
  this.name = "BackendOverrideError";
9064
9086
  }
9065
9087
  };
9066
9088
  function resolveBackendURL(env = process.env) {
9067
9089
  const requested = env.ITPAY_BACKEND_URL?.trim();
9068
- if (!requested || requested === DEFAULT_BASE_URL || requested === `${DEFAULT_BASE_URL}/`) return DEFAULT_BASE_URL;
9069
- if (requested === SANDBOX_BASE_URL || requested === `${SANDBOX_BASE_URL}/`) return SANDBOX_BASE_URL;
9070
- if (requested === DEV_BASE_URL || requested === `${DEV_BASE_URL}/`) return DEV_BASE_URL;
9090
+ if (!requested) return DEFAULT_BASE_URL;
9091
+ const official = OFFICIAL_BACKEND_URLS.find((origin) => requested === origin || requested === `${origin}/`);
9092
+ if (official) return official;
9071
9093
  if (env.ITPAY_CLI_DEV === "1" && /^http:\/\/(localhost|127\.0\.0\.1):\d+\/?$/.test(requested)) return requested.replace(/\/$/, "");
9072
9094
  throw new BackendOverrideError();
9073
9095
  }
@@ -9244,20 +9266,20 @@ function writeCommandEnvelope(value, options = {}) {
9244
9266
  `);
9245
9267
  }
9246
9268
  } else {
9247
- for (const [key, fact] of Object.entries(facts)) {
9248
- for (const line of plainValueLines(fact, key)) out(`${line}
9269
+ for (const [key, fact2] of Object.entries(facts)) {
9270
+ for (const line of plainValueLines(fact2, key)) out(`${line}
9249
9271
  `);
9250
9272
  }
9251
9273
  if ("error" in qualified && qualified.result) {
9252
- for (const [key, fact] of Object.entries(qualified.result)) {
9253
- for (const line of plainValueLines(fact, key)) out(`${line}
9274
+ for (const [key, fact2] of Object.entries(qualified.result)) {
9275
+ for (const line of plainValueLines(fact2, key)) out(`${line}
9254
9276
  `);
9255
9277
  }
9256
9278
  }
9257
9279
  }
9258
9280
  if ("handoff" in qualified && qualified.handoff) {
9259
- for (const [key, fact] of Object.entries(qualified.handoff)) {
9260
- for (const line of plainValueLines(fact, `handoff.${key}`)) out(`${line}
9281
+ for (const [key, fact2] of Object.entries(qualified.handoff)) {
9282
+ for (const line of plainValueLines(fact2, `handoff.${key}`)) out(`${line}
9261
9283
  `);
9262
9284
  }
9263
9285
  }
@@ -9383,8 +9405,8 @@ function purchaseEnvelope(state) {
9383
9405
  const review = state.review;
9384
9406
  return {
9385
9407
  status: state.status,
9386
- result: { service_execution_id: id, completed_stage: state.completed_stage, ...state.auto_wait_remaining_ms !== void 0 ? { auto_wait_remaining_ms: state.auto_wait_remaining_ms } : {}, effects: state.effects, ...review ? { summary: review.summary, price_kind: review.binding.price_kind, review_expires_at: review.binding.expires_at, input_template: fileInputTemplate(`itpay services purchase ${id} --input-json <purchase-confirmation.json> --json`, { ...review.confirmation_template }, ["user_approved", "user_answer", ...review.confirmation_template.price_policy.mode === "" ? ["price_policy"] : []], { executionID: id }) } : {} },
9387
- instruction: review ? `${state.status === "confirmation_changed" ? "\u8D2D\u4E70\u6761\u4EF6\u53D1\u751F\u53D8\u5316\uFF0C\u53EA\u8865\u5145\u5BF9\u53D8\u5316\u7684\u771F\u5B9E\u786E\u8BA4\u3002" : "\u6838\u5BF9\u5F53\u524D\u5BF9\u8C61\u3001\u6570\u91CF\u3001\u91D1\u989D\u4E0E\u6761\u6B3E\u3002"}\u5DF2\u6709\u660E\u786E\u540C\u610F\u4E14\u8986\u76D6\u8FD9\u4E9B\u6761\u4EF6\u65F6\u6CBF\u7528\uFF1B\u5426\u5219\u4EC5\u8865\u7F3A\u5931\u540C\u610F\u3002\u5C06\u5B8C\u6574 file_content \u5199\u5165\u6587\u4EF6\uFF0C\u586B\u5199\u771F\u5B9E\u56DE\u7B54\u548C\u660E\u786E\u4EF7\u683C\u7B56\u7565\u540E\u6267\u884C\u6A21\u677F\u3002\u672C\u6B65\u9AA4\u53EA\u751F\u6210\u5B98\u65B9\u586B\u5199\u4E0E\u4ED8\u6B3E\u9875\u9762\uFF0C\u4E0D\u53D1\u8D77\u652F\u4ED8\u3002\u672A\u77E5\u4EF7\u683C\u4E0D\u5F97\u9ED8\u8BA4\u6539\u6210\u5B98\u65B9\u9875\u786E\u8BA4\u3002` : state.status === "running" && state.auto_wait_remaining_ms === 0 ? "\u81EA\u52A8\u7B49\u5F85\u5DF2\u8FBE\u5230120\u79D2\u4E0A\u9650\uFF0C\u5DF2\u505C\u6B62\u3002\u539F\u786E\u8BA4\u548C\u539F\u8D2D\u4E70\u4FDD\u7559\uFF1B\u62A5\u544A completed_stage\uFF0C\u7528\u6237\u660E\u786E\u8981\u6C42\u6062\u590D\u65F6\u4F7F\u7528 recovery \u4E2D\u7684\u539F\u5355\u547D\u4EE4\uFF0C\u4E0D\u81EA\u52A8\u91CD\u542F\u7B49\u5F85\u3002" : state.status === "running" ? "\u5DF2\u4FDD\u5B58\u539F\u786E\u8BA4\uFF0C\u5F53\u524D\u5B8C\u6210\u9636\u6BB5\u89C1 completed_stage\u3002\u4FDD\u7559\u540C\u4E00\u4EFB\u52A1\u7EE7\u7EED\u6709\u754C\u7B49\u5F85\uFF1B\u4E0D\u8981\u6C42\u7528\u6237\u8BF4\u7EE7\u7EED\u3002\u7D2F\u8BA1120\u79D2\u4ECD\u672A\u5B8C\u6210\u65F6\u505C\u6B62\u81EA\u52A8\u7B49\u5F85\u5E76\u62A5\u544A\u539F\u8FDB\u5EA6\uFF0C\u4E0D\u521B\u5EFA\u66FF\u4EE3\u8D2D\u4E70\u3002" : state.status === "expired" ? "\u539F\u786E\u8BA4\u6216\u62A5\u4EF7\u5DF2\u5230\u671F\uFF0C\u4E0D\u80FD\u6CBF\u7528\u8FC7\u671F\u5165\u53E3\uFF1B\u4FDD\u7559\u539F\u8D2D\u4E70\u5E76\u6838\u5BF9\u5F53\u524D\u72B6\u6001\uFF0C\u4ED8\u6B3E\u672A\u77E5\u4E0D\u91CD\u5EFA\u3002" : "\u5F53\u524D\u8D2D\u4E70\u672A\u80FD\u7EE7\u7EED\uFF1B\u4FDD\u7559\u539F\u6267\u884C\uFF0C\u6309\u5F53\u524D\u539F\u56E0\u5904\u7406\uFF0C\u4E0D\u91CD\u5EFA\u8D2D\u4E70\u6216\u731C\u6D4B\u7ED3\u679C\u3002",
9408
+ result: { service_execution_id: id, completed_stage: state.completed_stage, ...state.auto_wait_remaining_ms !== void 0 ? { auto_wait_remaining_ms: state.auto_wait_remaining_ms } : {}, effects: state.effects, ...review ? { summary: review.summary, allowed_modes: review.allowed_modes, confirmation_schema: review.confirmation_schema, price_kind: review.binding.price_kind, review_expires_at: review.binding.expires_at, input_template: fileInputTemplate(`itpay services purchase ${id} --input-json <purchase-confirmation.json> --json`, { ...review.confirmation_template }, ["user_approved", "user_answer", ...review.confirmation_template.price_policy.mode === "" ? ["price_policy"] : []], { executionID: id }) } : {} },
9409
+ instruction: review ? `${state.status === "confirmation_changed" ? "\u8D2D\u4E70\u6761\u4EF6\u53D1\u751F\u53D8\u5316\uFF0C\u53EA\u8865\u5145\u5BF9\u53D8\u5316\u7684\u771F\u5B9E\u786E\u8BA4\u3002" : "\u6838\u5BF9\u5F53\u524D\u5BF9\u8C61\u3001\u6570\u91CF\u3001\u91D1\u989D\u4E0E\u6761\u6B3E\u3002"}\u5DF2\u6709\u660E\u786E\u540C\u610F\u4E14\u8986\u76D6\u8FD9\u4E9B\u6761\u4EF6\u65F6\u6CBF\u7528\uFF1B\u5426\u5219\u4EC5\u8865\u7F3A\u5931\u540C\u610F\u3002\u5C06\u5B8C\u6574 file_content \u5199\u5165\u6587\u4EF6\uFF0C\u586B\u5199\u771F\u5B9E\u56DE\u7B54\u548C\u660E\u786E\u4EF7\u683C\u7B56\u7565\u540E\u6267\u884C\u6A21\u677F\u3002\u672C\u6B65\u9AA4\u7684\u6548\u679C\u4EE5 effects \u548C\u5F53\u524D\u670D\u52A1\u5408\u540C\u4E3A\u51C6\uFF1B\u4E0D\u53D1\u8D77\u652F\u4ED8\u4E0D\u80FD\u63A8\u65AD\u6CA1\u6709\u8BA2\u5355\u6216\u5E93\u5B58\u6548\u679C\u3002\u5BBF\u4E3B\u539F\u751F\u6279\u51C6\u4E0E\u4E1A\u52A1\u540C\u610F\u5206\u522B\u4FDD\u7559\u3002\u672A\u77E5\u4EF7\u683C\u4E0D\u5F97\u9ED8\u8BA4\u6539\u6210\u5B98\u65B9\u9875\u786E\u8BA4\u3002` : state.status === "running" && state.auto_wait_remaining_ms === 0 ? "\u81EA\u52A8\u7B49\u5F85\u5DF2\u8FBE\u5230120\u79D2\u4E0A\u9650\uFF0C\u5DF2\u505C\u6B62\u3002\u539F\u786E\u8BA4\u548C\u539F\u8D2D\u4E70\u4FDD\u7559\uFF1B\u62A5\u544A completed_stage\uFF0C\u7528\u6237\u660E\u786E\u8981\u6C42\u6062\u590D\u65F6\u4F7F\u7528 recovery \u4E2D\u7684\u539F\u5355\u547D\u4EE4\uFF0C\u4E0D\u81EA\u52A8\u91CD\u542F\u7B49\u5F85\u3002" : state.status === "running" ? "\u5DF2\u4FDD\u5B58\u539F\u786E\u8BA4\uFF0C\u5F53\u524D\u5B8C\u6210\u9636\u6BB5\u89C1 completed_stage\u3002\u4FDD\u7559\u540C\u4E00\u4EFB\u52A1\u7EE7\u7EED\u6709\u754C\u7B49\u5F85\uFF1B\u4E0D\u8981\u6C42\u7528\u6237\u8BF4\u7EE7\u7EED\u3002\u7D2F\u8BA1120\u79D2\u4ECD\u672A\u5B8C\u6210\u65F6\u505C\u6B62\u81EA\u52A8\u7B49\u5F85\u5E76\u62A5\u544A\u539F\u8FDB\u5EA6\uFF0C\u4E0D\u521B\u5EFA\u66FF\u4EE3\u8D2D\u4E70\u3002" : state.status === "expired" ? "\u539F\u786E\u8BA4\u6216\u62A5\u4EF7\u5DF2\u5230\u671F\uFF0C\u4E0D\u80FD\u6CBF\u7528\u8FC7\u671F\u5165\u53E3\uFF1B\u4FDD\u7559\u539F\u8D2D\u4E70\u5E76\u6838\u5BF9\u5F53\u524D\u72B6\u6001\uFF0C\u4ED8\u6B3E\u672A\u77E5\u4E0D\u91CD\u5EFA\u3002" : "\u5F53\u524D\u8D2D\u4E70\u672A\u80FD\u7EE7\u7EED\uFF1B\u4FDD\u7559\u539F\u6267\u884C\uFF0C\u6309\u5F53\u524D\u539F\u56E0\u5904\u7406\uFF0C\u4E0D\u91CD\u5EFA\u8D2D\u4E70\u6216\u731C\u6D4B\u7ED3\u679C\u3002",
9388
9410
  next: state.status === "running" && state.auto_wait_remaining_ms !== 0 ? resume : null,
9389
9411
  recovery: state.status === "running" && state.auto_wait_remaining_ms === 0 ? [{ ...resume, reason: "\u4EC5\u7528\u6237\u660E\u786E\u8981\u6C42\u7EE7\u7EED\u65F6\u6062\u590D\u539F\u8D2D\u4E70\uFF1B\u4E0D\u81EA\u52A8\u91CD\u542F\u7B49\u5F85" }] : state.status === "blocked" || state.status === "expired" ? [{ command: `itpay services next ${id} --json`, reason: "\u8BFB\u53D6\u539F\u6267\u884C\u7684\u5F53\u524D\u4E8B\u5B9E\u4E0E\u5B8C\u6574\u6062\u590D\u52A8\u4F5C\uFF1B\u4E0D\u65B0\u5EFA\u8D2D\u4E70" }] : []
9390
9412
  };
@@ -9436,6 +9458,7 @@ function defaultHostForAgentType(agentType) {
9436
9458
  const normalized = agentType?.trim().toLowerCase() ?? "";
9437
9459
  if (normalized === "codex-desktop") return "codex";
9438
9460
  if (normalized === "claude-code-desktop") return "claude-code";
9461
+ if (normalized === "dot" || normalized === "muse" || normalized === "hermes") return "plain-chat";
9439
9462
  if (normalized === "workbuddy") return "plain-chat";
9440
9463
  if (normalized === "zcode") return "plain-chat";
9441
9464
  if (normalized === "doubao-work") return "plain-chat";
@@ -9515,228 +9538,6 @@ function hostCapabilities(host) {
9515
9538
  }
9516
9539
  __name(hostCapabilities, "hostCapabilities");
9517
9540
 
9518
- // src/render/telegram.ts
9519
- function buttonsFor(plan) {
9520
- if (plan.kind === "payment_qr" && plan.paymentIntentID) {
9521
- return [
9522
- { label: "\u652F\u4ED8\u9047\u5230\u95EE\u9898 / \u5237\u65B0", kind: "callback", intent: "refresh_payment_qr", ref: plan.paymentIntentID },
9523
- { label: "\u6211\u5DF2\u4ED8\u6B3E\uFF0C\u67E5\u8BE2\u72B6\u6001", kind: "callback", intent: "check_payment_status", ref: plan.paymentIntentID }
9524
- ];
9525
- }
9526
- if (plan.kind === "auth_qr" && plan.checkoutID) {
9527
- return [
9528
- { label: "\u6253\u5F00\u6388\u6743\u9875\u9762", kind: "url", url: plan.url },
9529
- { label: "\u67E5\u8BE2\u6388\u6743\u72B6\u6001", kind: "callback", intent: "check_checkout_status", ref: plan.checkoutID }
9530
- ];
9531
- }
9532
- return [
9533
- { label: "\u{1F4F1} \u624B\u673A\u70B9\u8FD9\u513F\u652F\u4ED8", kind: "url", url: plan.url },
9534
- ...plan.checkoutID ? [{ label: "\u{1F4CB} \u5DF2\u6388\u6743\u7ED9\u6211\u8BFB", kind: "callback", intent: "grant_confirmed", ref: plan.checkoutID }] : []
9535
- ];
9536
- }
9537
- __name(buttonsFor, "buttonsFor");
9538
- function nativeButton(button) {
9539
- if (button.kind === "url") {
9540
- return { label: button.label, url: button.url ?? "" };
9541
- }
9542
- const value = button.intent === "check_checkout_status" ? `itp:checkout:${button.ref ?? ""}` : `itp:${button.intent ?? "callback"}:${button.ref ?? ""}`;
9543
- return { label: button.label, value };
9544
- }
9545
- __name(nativeButton, "nativeButton");
9546
- function renderTelegram(plan, options) {
9547
- const out = options.output ?? ((line) => process.stdout.write(line));
9548
- const agentAction = buildOpenClawTelegramAction(plan, options.target);
9549
- const presentation = agentAction.arguments.presentation;
9550
- const media = collectTelegramMedia(plan);
9551
- const text = agentAction.arguments.message;
9552
- const openclawMessage = {
9553
- command: [
9554
- "openclaw",
9555
- "message",
9556
- "send",
9557
- "--channel",
9558
- "telegram",
9559
- "--target",
9560
- options.target,
9561
- "--message",
9562
- text,
9563
- ...media.length > 0 ? ["--media", media[0].url] : [],
9564
- "--presentation",
9565
- JSON.stringify(presentation)
9566
- ],
9567
- // Keep the same Checkout visible if native buttons are unavailable.
9568
- if_unavailable: "If `openclaw message send` is unavailable, send the same QR media and Checkout URL as ordinary Telegram content, report that inline buttons are unavailable, and stop. Do not create another Checkout."
9569
- };
9570
- out(JSON.stringify({ presentation, agent_action: agentAction, openclaw_message: openclawMessage }, null, 2) + "\n");
9571
- }
9572
- __name(renderTelegram, "renderTelegram");
9573
- function buildOpenClawTelegramAction(plan, target2) {
9574
- const buttons = buttonsFor(plan).map(nativeButton);
9575
- const media = collectTelegramMedia(plan);
9576
- const message = plan.kind === "payment_qr" ? `ItPay payment QR \u2014 ${plan.summary}` : plan.kind === "auth_qr" ? `ItPay auth required \u2014 ${plan.summary}` : `ItPay checkout QR \u2014 ${plan.summary}`;
9577
- const presentation = {
9578
- blocks: [{ type: "buttons", buttons }]
9579
- };
9580
- const nativeTarget = target2.trim().replace(/^telegram:/i, "");
9581
- return {
9582
- tool: "message",
9583
- arguments: {
9584
- action: "send",
9585
- channel: "telegram",
9586
- target: nativeTarget,
9587
- message,
9588
- ...media[0]?.url ? { media: media[0].url } : {},
9589
- presentation
9590
- }
9591
- };
9592
- }
9593
- __name(buildOpenClawTelegramAction, "buildOpenClawTelegramAction");
9594
- function collectTelegramMedia(plan) {
9595
- const media = (plan.platform.media ?? []).map((item) => ({
9596
- url: item.url,
9597
- mimeType: item.mimeType ?? "image/png"
9598
- }));
9599
- if (plan.kind === "payment_qr" || media.length === 0) {
9600
- media.unshift({
9601
- url: plan.preferredQRSources.find((src) => src.length > 0) ?? plan.url,
9602
- mimeType: "image/png"
9603
- });
9604
- }
9605
- return media;
9606
- }
9607
- __name(collectTelegramMedia, "collectTelegramMedia");
9608
-
9609
- // src/render/checkout_handoff.ts
9610
- function shouldPrepareLocalCheckoutImage(platform2) {
9611
- return platform2 === "markdown";
9612
- }
9613
- __name(shouldPrepareLocalCheckoutImage, "shouldPrepareLocalCheckoutImage");
9614
- function isWorkBuddyPlainChat(agentType, platform2) {
9615
- return agentType?.trim().toLowerCase() === "workbuddy" && platform2 === "plain_chat";
9616
- }
9617
- __name(isWorkBuddyPlainChat, "isWorkBuddyPlainChat");
9618
- function isZCodePlainChat(agentType, platform2) {
9619
- return agentType?.trim().toLowerCase() === "zcode" && platform2 === "plain_chat";
9620
- }
9621
- __name(isZCodePlainChat, "isZCodePlainChat");
9622
- function isLinkOnlyBrowserAgent(agentType, platform2) {
9623
- return isWorkBuddyPlainChat(agentType, platform2) || isZCodePlainChat(agentType, platform2);
9624
- }
9625
- __name(isLinkOnlyBrowserAgent, "isLinkOnlyBrowserAgent");
9626
- function buildWorkBuddyPresentFilesAction(url) {
9627
- return {
9628
- tool: "present_files",
9629
- arguments: { files: [url] }
9630
- };
9631
- }
9632
- __name(buildWorkBuddyPresentFilesAction, "buildWorkBuddyPresentFilesAction");
9633
- function hasCompleteCheckoutTokens(url) {
9634
- if (!url) {
9635
- return false;
9636
- }
9637
- try {
9638
- const parsed = new URL(url);
9639
- return Boolean(parsed.searchParams.get("display_token") && parsed.searchParams.get("complete_exchange_token"));
9640
- } catch {
9641
- return false;
9642
- }
9643
- }
9644
- __name(hasCompleteCheckoutTokens, "hasCompleteCheckoutTokens");
9645
- function buildCheckoutHandoff(input) {
9646
- const url = input.plan?.localSimulation && input.mobileUrl && hasCompleteCheckoutTokens(input.mobileUrl) ? input.mobileUrl : input.url;
9647
- const handoff = { url, ...input.plan?.localSimulation ? { environment: "local_simulation", query: "live", transactions: "simulated" } : {} };
9648
- const mobileUrl = !input.plan?.localSimulation && hasCompleteCheckoutTokens(input.mobileUrl) ? input.mobileUrl : void 0;
9649
- if (mobileUrl) {
9650
- handoff.mobile_url = mobileUrl;
9651
- }
9652
- const workBuddyAction = isWorkBuddyPlainChat(input.agentType, input.platform);
9653
- if (workBuddyAction) {
9654
- handoff.agent_action = buildWorkBuddyPresentFilesAction(url);
9655
- }
9656
- if (input.platform === "markdown") {
9657
- if (input.localPath) handoff.qr_local_path = input.localPath;
9658
- if (input.markdown) handoff.markdown = input.markdown;
9659
- } else if (input.platform === "plain_chat" && input.qrImageURL && !isLinkOnlyBrowserAgent(input.agentType, input.platform)) {
9660
- handoff.qr_image_url = input.qrImageURL;
9661
- } else if (input.platform === "telegram" && input.qrImageURL) {
9662
- handoff.qr_image_url = input.qrImageURL;
9663
- }
9664
- if (input.agentType?.trim().toLowerCase() === "openclaw" && input.platform === "telegram" && input.plan && input.target) {
9665
- handoff.agent_action = buildOpenClawTelegramAction(input.plan, input.target);
9666
- }
9667
- return {
9668
- handoff,
9669
- instruction: input.plan?.localSimulation ? `\u672C\u5730\u5B9E\u9A8C\uFF1A\u94C1\u8DEF\u4E0E\u5730\u56FE\u67E5\u8BE2\u771F\u5B9E\uFF0C\u6388\u6743\u3001\u901A\u77E5\u548C\u4EA4\u6613\u6A21\u62DF\uFF0C\u4E0D\u4F1A\u6263\u6B3E\u3002\u5728\u672C\u673A\u6253\u5F00 handoff.url \u6A21\u62DF\u4ED8\u6B3E\u5165\u53E3\uFF0C\u91D1\u989D ${input.amount}\uFF1B\u4EC5\u672C\u673A\u684C\u9762\u53EF\u8FBE\u3002${workBuddyAction ? "\u6309 handoff.agent_action \u539F\u6837\u6253\u5F00\u4E00\u6B21\u3002" : "\u5C55\u793A\u539F\u5165\u53E3\u3002"}\u7B49\u5F85\u7528\u6237\u64CD\u4F5C\u540E\u8BFB\u53D6\u540C\u4E00 Checkout\uFF1B\u4E0D\u521B\u5EFA\u66FF\u4EE3\u8BA2\u5355\uFF0C\u7528\u6237\u58F0\u660E\u4E0D\u8BC1\u660E\u6A21\u62DF\u4ED8\u6B3E\u5DF2\u786E\u8BA4\u3002` : `\u5148\u5C55\u793A\u5B98\u65B9\u5165\u53E3\uFF0C\u518D\u505A\u975E\u5FC5\u8981\u8BB0\u5FC6\u6216\u65E5\u5FD7\uFF1B\u4FDD\u7559\u5FC5\u9700\u5B89\u5168\u68C0\u67E5\u548C\u5BBF\u4E3B\u6743\u9650\u3002${checkoutHandoffInstruction(input.agentType, input.platform, input.amount, Boolean(mobileUrl))}`
9670
- };
9671
- }
9672
- __name(buildCheckoutHandoff, "buildCheckoutHandoff");
9673
- function checkoutHandoffInstruction(agentType, platform2, amount, hasMobileLink) {
9674
- if (isWorkBuddyPlainChat(agentType, platform2)) {
9675
- const mobileSentence = hasMobileLink ? "\uFF0C\u7136\u540E\u628A handoff.mobile_url \u4F5C\u4E3A\u53EF\u70B9\u51FB\u94FE\u63A5\u53D1\u7ED9\u7528\u6237\uFF0C\u8BF4\u660E\u201C\u624B\u673A\u7AEF\u70B9\u5F00\u53EF\u76F4\u63A5\u8DF3\u8F6C\u652F\u4ED8\u5B9D\u6216\u5FAE\u4FE1\u652F\u4ED8\uFF1B\u5C0F\u7A0B\u5E8F\u5185\u6253\u4E0D\u5F00\u65F6\u590D\u5236\u5230\u624B\u673A\u6D4F\u89C8\u5668\u6253\u5F00\u5373\u53EF\u201D" : "";
9676
- const failLinks = hasMobileLink ? "\u53D1\u9001 handoff.url \u4E0E handoff.mobile_url" : "\u53D1\u9001\u539F\u59CB handoff.url";
9677
- return `Backend \u5C1A\u672A\u786E\u8BA4\u4ED8\u6B3E\u3002\u82E5\u5F53\u524D\u53EF\u7528 present_files\uFF0C\u6309 handoff.agent_action \u539F\u6837\u6267\u884C\u4E00\u6B21\uFF1B\u4E0D\u53EF\u7528\u5219\u5F53\u8F6E\u76F4\u63A5\u5C55\u793A\u539F\u94FE\u63A5\uFF0C\u5728\u53F3\u4FA7\u6253\u5F00 handoff.url\uFF1B\u5DE5\u5177\u6210\u529F\u6216\u76F4\u63A5\u5C55\u793A\u94FE\u63A5\u540E\u8BF4\u660E\u91D1\u989D ${amount}${mobileSentence}\uFF0C\u7136\u540E\u505C\u6B62\u7B49\u5F85\u3002\u82E5\u5DE5\u5177\u5931\u8D25\uFF0C\u53EA${failLinks}\uFF0C\u62A5\u544A\u672A\u81EA\u52A8\u6253\u5F00\u5E76\u505C\u6B62\u3002\u4E0D\u8981\u7528 present_files \u6253\u5F00\u672C\u5730\u6587\u4EF6\u6216\u4E8C\u7EF4\u7801 PNG\uFF0C\u4E0D\u8981\u4E0B\u8F7D\u6216\u91CD\u5EFA\u4E8C\u7EF4\u7801\uFF0C\u4E0D\u8981\u8C03\u7528 pay\uFF0C\u4E0D\u8981\u521B\u5EFA\u65B0 Checkout\u3001Payment Intent \u6216 Execution\u3002\u53EA\u6709\u7528\u6237\u660E\u786E\u8868\u793A\u5DF2\u4ED8\u6B3E\u6216\u8981\u6C42\u67E5\u8BE2\u72B6\u6001\u65F6\uFF0C\u624D\u6267\u884C next.command\uFF1B\u7528\u6237\u7684\u8BDD\u4E0D\u662F\u4ED8\u6B3E\u6210\u529F\u8BC1\u660E\u3002`;
9678
- }
9679
- if (isZCodePlainChat(agentType, platform2)) {
9680
- const mobileSentence = hasMobileLink ? "\uFF0C\u5E76\u628A handoff.mobile_url \u53D1\u7ED9\u7528\u6237\u5907\u7528\uFF08\u624B\u673A\u7AEF\u70B9\u5F00\u53EF\u76F4\u63A5\u8DF3\u8F6C\u652F\u4ED8\u5B9D\u6216\u5FAE\u4FE1\u652F\u4ED8\uFF09" : "";
9681
- const fallbackLinks = hasMobileLink ? "\u540C\u4E00\u4E2A\u53EF\u70B9\u51FB handoff.url \u4E0E handoff.mobile_url" : "\u540C\u4E00\u4E2A\u53EF\u70B9\u51FB handoff.url";
9682
- return `Backend \u5C1A\u672A\u786E\u8BA4\u4ED8\u6B3E\u3002\u7ACB\u5373\u7528 ZCode \u5185\u7F6E\u6D4F\u89C8\u5668\u6253\u5F00 handoff.url\uFF0C\u8BA9\u7528\u6237\u5B8C\u6210\u4ED8\u6B3E\uFF1B\u786E\u8BA4\u5DF2\u53D1\u8D77\u6253\u5F00\u540E\u8BF4\u660E\u91D1\u989D ${amount}${mobileSentence}\uFF0C\u7136\u540E\u505C\u6B62\u7B49\u5F85\u3002\u5DE5\u5177\u4E0D\u53EF\u7528\u65F6\u76F4\u63A5\u5C55\u793A\u94FE\u63A5\uFF0C\u4E0D\u8981\u4E0B\u8F7D\u3001\u89E3\u6790\u6216\u91CD\u5EFA\u4E8C\u7EF4\u7801\uFF0C\u4E0D\u8981\u521B\u5EFA\u65B0 Checkout\u3001Payment Intent \u6216 Execution\u3002\u53EA\u6709\u5185\u7F6E\u6D4F\u89C8\u5668\u660E\u786E\u4E0D\u53EF\u7528\u65F6\uFF0C\u624D\u5C55\u793A${fallbackLinks}\u3002\u53EA\u6709\u7528\u6237\u660E\u786E\u8868\u793A\u5DF2\u4ED8\u6B3E\u6216\u8981\u6C42\u67E5\u8BE2\u72B6\u6001\u65F6\uFF0C\u624D\u6267\u884C next.command\uFF1B\u7528\u6237\u7684\u8BDD\u4E0D\u662F\u4ED8\u6B3E\u6210\u529F\u8BC1\u660E\u3002`;
9683
- }
9684
- if (agentType?.trim().toLowerCase() === "doubao-work" && platform2 === "plain_chat") {
9685
- const directLink = hasMobileLink ? "handoff.mobile_url" : "handoff.url";
9686
- const directLabel = hasMobileLink ? "\u624B\u673A\u76F4\u63A5\u6253\u5F00\u6536\u94F6\u53F0\uFF08\u53EF\u8DF3\u8F6C\u652F\u4ED8\u5B9D/\u5FAE\u4FE1\uFF09" : "\u624B\u673A\u76F4\u63A5\u6253\u5F00\u6536\u94F6\u53F0";
9687
- return `Backend \u5C1A\u672A\u786E\u8BA4\u4ED8\u6B3E\u3002\u5728\u5F53\u524D\u8C46\u5305\u5DE5\u4F5C\u5BF9\u8BDD\u4E2D\u5C55\u793A\u4E24\u4E2A\u6709\u6807\u7B7E\u7684\u5B98\u65B9\u5165\u53E3\uFF1A\u5C06 ${directLink} \u6807\u4E3A\u201C${directLabel}\u201D\uFF0C\u5C06 handoff.qr_image_url \u6807\u4E3A\u201C\u4E8C\u7EF4\u7801\u56FE\u7247\uFF08\u4FDD\u5B58\u6216\u7528\u53E6\u4E00\u53F0\u8BBE\u5907\u626B\u7801\uFF09\u201D\u3002\u8BF4\u660E\u91D1\u989D ${amount} \u540E\u505C\u6B62\u7B49\u5F85\u3002\u4E0D\u8981\u89E3\u6790\u6216\u5355\u72EC\u8F93\u51FA URL credential\uFF0C\u4E0D\u8981\u4E0B\u8F7D\u6216\u91CD\u5EFA\u4E8C\u7EF4\u7801\uFF0C\u4E0D\u8981\u8C03\u7528 pay\uFF0C\u4E0D\u8981\u521B\u5EFA\u65B0 Checkout\u3001Payment Intent \u6216 Execution\u3002\u53EA\u6709\u7528\u6237\u660E\u786E\u8868\u793A\u5DF2\u4ED8\u6B3E\u6216\u8981\u6C42\u67E5\u8BE2\u72B6\u6001\u65F6\uFF0C\u624D\u6267\u884C next.command\uFF1B\u7528\u6237\u7684\u8BDD\u4E0D\u662F\u4ED8\u6B3E\u6210\u529F\u8BC1\u660E\u3002`;
9688
- }
9689
- if (platform2 === "markdown") {
9690
- const mobileSentence = hasMobileLink ? "\uFF0C\u5E76\u9644 handoff.mobile_url \u4F9B\u624B\u673A\u7AEF\u70B9\u51FB\u76F4\u8FBE\u652F\u4ED8" : "";
9691
- return `Backend \u5C1A\u672A\u786E\u8BA4\u4ED8\u6B3E\u3002\u628A handoff.markdown \u539F\u6837\u53D1\u9001\u5230\u5F53\u524D\u684C\u9762\u5BF9\u8BDD\uFF0C\u786E\u8BA4\u4E8C\u7EF4\u7801\u3001\u4ED8\u6B3E\u94FE\u63A5\u548C\u91D1\u989D ${amount} \u5747\u5DF2\u5B9E\u9645\u5BF9\u7528\u6237\u53EF\u89C1${mobileSentence}\uFF0C\u7136\u540E\u505C\u6B62\u7B49\u5F85\u3002\u4E0D\u8981\u521B\u5EFA\u65B0 Checkout\u3001Payment Intent \u6216 Execution\uFF1B\u53EA\u6709\u7528\u6237\u660E\u786E\u8868\u793A\u5DF2\u4ED8\u6B3E\u6216\u8981\u6C42\u67E5\u8BE2\u72B6\u6001\u65F6\uFF0C\u624D\u6267\u884C next.command\uFF1B\u7528\u6237\u7684\u8BDD\u4E0D\u662F\u4ED8\u6B3E\u6210\u529F\u8BC1\u660E\u3002`;
9692
- }
9693
- if (platform2 === "terminal") {
9694
- const mobileSentence = hasMobileLink ? "\uFF0C\u5E76\u5C55\u793A handoff.mobile_url \u4F9B\u624B\u673A\u7AEF\u70B9\u51FB\u76F4\u8FBE\u652F\u4ED8" : "";
9695
- return `Backend \u5C1A\u672A\u786E\u8BA4\u4ED8\u6B3E\u3002\u5728\u7528\u6237\u53EF\u89C1\u7EC8\u7AEF\u5C55\u793A\u5F53\u524D Checkout \u7684\u4E8C\u7EF4\u7801\u3001handoff.url \u548C\u91D1\u989D ${amount}${mobileSentence}\uFF0C\u7136\u540E\u505C\u6B62\u7B49\u5F85\u3002\u4E0D\u8981\u521B\u5EFA\u65B0 Checkout\u3001Payment Intent \u6216 Execution\uFF1B\u53EA\u6709\u7528\u6237\u660E\u786E\u8868\u793A\u5DF2\u4ED8\u6B3E\u6216\u8981\u6C42\u67E5\u8BE2\u72B6\u6001\u65F6\uFF0C\u624D\u6267\u884C next.command\uFF1B\u7528\u6237\u7684\u8BDD\u4E0D\u662F\u4ED8\u6B3E\u6210\u529F\u8BC1\u660E\u3002`;
9696
- }
9697
- if (agentType?.trim().toLowerCase() === "openclaw" && platform2 === "telegram") {
9698
- const failLinks = hasMobileLink ? "handoff.qr_image_url\u3001\u91D1\u989D\u3001handoff.url \u4E0E handoff.mobile_url" : "handoff.qr_image_url\u3001\u91D1\u989D\u548C handoff.url";
9699
- return `Backend \u5C1A\u672A\u786E\u8BA4\u4ED8\u6B3E\u6216\u6388\u6743\u72B6\u6001\u3002\u82E5\u5F53\u524D\u5DF2\u6709\u53EF\u7528 OpenClaw \u539F\u751F message tool\uFF0C\u4E25\u683C\u6309 handoff.agent_action.tool \u548C handoff.agent_action.arguments \u539F\u6837\u6267\u884C\uFF1B\u5B83\u4F1A\u53D1\u9001\u91D1\u989D ${amount}\u3001\u4E8C\u7EF4\u7801\u3001\u{1F4F1} \u624B\u673A\u70B9\u8FD9\u513F\u652F\u4ED8\u548C \u{1F4CB} \u5DF2\u6388\u6743\u7ED9\u6211\u8BFB\u3002\u4E0D\u5F97\u6539\u5199 presentation\u3001\u6362\u7528\u5176\u4ED6\u6D88\u606F\u5DE5\u5177\u3001\u62C6\u5F00\u6309\u94AE\u53D1\u9001\u6216\u7528\u666E\u901A\u56DE\u590D\u58F0\u79F0\u6309\u94AE\u5DF2\u7ECF\u53D1\u9001\u3002\u5DE5\u5177\u4E0D\u53EF\u7528\u65F6\u5F53\u8F6E\u76F4\u63A5\u5C55\u793A\u5DF2\u6709\u5B98\u65B9\u94FE\u63A5\uFF0C\u4E0D\u7814\u7A76\u6216\u5B89\u88C5\u5DE5\u5177\uFF1B\u5DE5\u5177\u6210\u529F\u6216\u5C55\u793A\u94FE\u63A5\u540E\u505C\u6B62\u7B49\u5F85\u3002\u6536\u5230 callback_data "itp:grant_confirmed:<checkout_id>" \u65F6\uFF0C\u8868\u793A\u7528\u6237\u58F0\u660E\u5DF2\u5728\u6536\u94F6\u53F0\u6388\u6743\u8BFB\u53D6\uFF1B\u7ACB\u5373\u6267\u884C next.command \u67E5\u8BE2\u540C\u4E00 Checkout\uFF0C\u518D\u53EA\u6267\u884C Backend \u8FD4\u56DE\u7684 next.command \u8FDB\u5165\u540C\u4E00 Execution \u7684 grant \u6D41\u7A0B\u3002\u8BE5 callback \u4E0D\u8BC1\u660E\u4ED8\u6B3E\u6210\u529F\u6216 grant \u5DF2\u751F\u6548\uFF1BBackend \u672A\u8FD4\u56DE grant_active \u524D\u4E0D\u5F97\u8BFB\u53D6\u6216\u731C\u6D4B\u7ED3\u679C\u3002\u82E5\u539F\u751F message tool \u660E\u786E\u5931\u8D25\u6216\u5F53\u524D Telegram \u672A\u542F\u7528 inline buttons\uFF0C\u53EA\u53D1\u9001\u73B0\u6709 ${failLinks}\uFF0C\u62A5\u544A\u6309\u94AE\u4E0D\u53EF\u7528\u5E76\u505C\u6B62\uFF1B\u4E0D\u8981\u521B\u5EFA\u65B0\u7684 Checkout\u3001Payment Intent \u6216 Execution\u3002`;
9700
- }
9701
- const urlList = hasMobileLink ? "handoff.url\u3001handoff.mobile_url\uFF08\u624B\u673A\u7AEF\u70B9\u51FB\u76F4\u8FBE\u652F\u4ED8\uFF09\u548C\u53EF\u7528\u7684 handoff.qr_image_url" : "handoff.url \u548C\u53EF\u7528\u7684 handoff.qr_image_url";
9702
- return `Backend \u5C1A\u672A\u786E\u8BA4\u4ED8\u6B3E\u3002\u628A ${urlList} \u5B9E\u9645\u53D1\u9001\u5230\u5F53\u524D\u4F1A\u8BDD\uFF0C\u8BF4\u660E\u91D1\u989D ${amount}\uFF0C\u7136\u540E\u505C\u6B62\u7B49\u5F85\u3002\u4E0D\u8981\u521B\u5EFA\u65B0 Checkout\u3001Payment Intent \u6216 Execution\uFF1B\u53EA\u6709\u7528\u6237\u660E\u786E\u8868\u793A\u5DF2\u4ED8\u6B3E\u6216\u8981\u6C42\u67E5\u8BE2\u72B6\u6001\u65F6\uFF0C\u624D\u6267\u884C next.command\uFF1B\u7528\u6237\u7684\u8BDD\u4E0D\u662F\u4ED8\u6B3E\u6210\u529F\u8BC1\u660E\u3002`;
9703
- }
9704
- __name(checkoutHandoffInstruction, "checkoutHandoffInstruction");
9705
-
9706
- // src/commands/checkout_handoff.ts
9707
- var payableStates = ["draft", "quote_bound", "auth_required", "payment_required"];
9708
- function assertCheckoutCreation(checkout, cartID, sourceExecutionID) {
9709
- const current = checkout.checkout;
9710
- if (!current.checkout_id || current.cart_id !== cartID || !payableStates.includes(current.status) || !checkout.display_token) {
9711
- throw checkoutNotPayable(current, cartID, sourceExecutionID, false);
9712
- }
9713
- }
9714
- __name(assertCheckoutCreation, "assertCheckoutCreation");
9715
- function assertCheckoutPayable(checkout, authoritative, cartID, sourceExecutionID) {
9716
- const current = authoritative?.checkout ?? checkout.checkout;
9717
- const deadlineClosed = authoritative?.payment_remaining_seconds === 0 || current.expires_at !== void 0 && (!authoritative?.server_now || Date.parse(current.expires_at) <= Date.parse(authoritative.server_now));
9718
- if (current.cart_id && current.cart_id !== cartID || !payableStates.includes(current.status) || authoritative?.payment_intents.some((intent) => !["failed", "cancelled", "expired"].includes(intent.status)) || deadlineClosed || !checkout.display_token) {
9719
- throw checkoutNotPayable(current, cartID, sourceExecutionID, deadlineClosed);
9720
- }
9721
- }
9722
- __name(assertCheckoutPayable, "assertCheckoutPayable");
9723
- function checkoutNotPayable(current, cartID, sourceExecutionID, deadlineClosed) {
9724
- return new CommandContractError(
9725
- "checkout_not_payable",
9726
- "original checkout is not a current payable entry",
9727
- "\u539FCheckout\u4E0D\u53EF\u4F5C\u4E3A\u65B0\u4ED8\u6B3E\u5165\u53E3\uFF1B\u6838\u5BF9\u539F\u8BA2\u5355\u3002\u8FC7\u671F\u4E0D\u7EED\u671F\uFF0C\u4ED8\u6B3E\u5904\u7406\u4E2D\u6216\u672A\u77E5\u4E0D\u91CD\u653E\uFF0C\u4E0D\u6362\u8D2D\u7269\u8F66\u6216\u5E42\u7B49\u952E\u521B\u5EFA\u66FF\u4EE3\u8D2D\u4E70\u3002",
9728
- sourceExecutionID ? [{ command: `itpay services next ${sourceExecutionID} --json`, reason: "\u8BFB\u53D6\u6765\u6E90\u6267\u884C\u7684\u539F\u8BA2\u5355\u4E0E\u4ED8\u6B3E\u4E8B\u5B9E" }] : [],
9729
- void 0,
9730
- {
9731
- cart_id: cartID,
9732
- checkout_id: current.checkout_id,
9733
- checkout_status: current.status,
9734
- reason: deadlineClosed ? "payment_window_closed" : "checkout_not_payable"
9735
- }
9736
- );
9737
- }
9738
- __name(checkoutNotPayable, "checkoutNotPayable");
9739
-
9740
9541
  // node_modules/zod/v3/external.js
9741
9542
  var external_exports = {};
9742
9543
  __export(external_exports, {
@@ -9883,10 +9684,10 @@ var util;
9883
9684
  return obj[e];
9884
9685
  });
9885
9686
  };
9886
- util2.objectKeys = typeof Object.keys === "function" ? (obj) => Object.keys(obj) : (object) => {
9687
+ util2.objectKeys = typeof Object.keys === "function" ? (obj) => Object.keys(obj) : (object3) => {
9887
9688
  const keys = [];
9888
- for (const key in object) {
9889
- if (Object.prototype.hasOwnProperty.call(object, key)) {
9689
+ for (const key in object3) {
9690
+ if (Object.prototype.hasOwnProperty.call(object3, key)) {
9890
9691
  keys.push(key);
9891
9692
  }
9892
9693
  }
@@ -13921,31 +13722,369 @@ var coerce = {
13921
13722
  };
13922
13723
  var NEVER = INVALID;
13923
13724
 
13924
- // src/services/rail/aftercare.ts
13925
- var target = external_exports.object({ leg_index: external_exports.number().int().nonnegative(), passenger_index: external_exports.number().int().nonnegative() }).strict();
13926
- var inputSchema = external_exports.object({ operation: external_exports.enum(["refund", "change"]), targets: external_exports.array(target).min(1).max(15), reason: external_exports.string().trim().min(1).max(1e3), scope_revision: external_exports.literal(1), user_confirmed_scope: external_exports.literal(true), change: external_exports.object({ travel_date: external_exports.string().optional(), departure_after: external_exports.string().optional(), arrival_before: external_exports.string().optional(), seat_type: external_exports.string().optional(), train_code: external_exports.string().optional(), constraints: external_exports.string().min(1).max(1e3) }).strict().optional() }).strict();
13927
- var responseSchema = external_exports.object({ expected_revision: external_exports.number().int().positive(), proposal_revision: external_exports.number().int().positive().optional(), user_approved: external_exports.boolean().optional(), additional_information: external_exports.string().max(1e3).optional(), reason: external_exports.string().max(1e3).optional() }).strict();
13928
- function railAftercareList(directory, orderID) {
13929
- return { status: "aftercare_directory", result: { ...directory }, instruction: directory.instruction + "\u6BB5/\u4E58\u5BA2\u7D22\u5F15\u4ECE0\u8D77\uFF0C\u6309\u8FD4\u56DE\u4E8B\u5B9E\u9009\u76EE\u6807\uFF1B\u660E\u786E\u2018\u7B2C\u4E8C\u6BB5\u2019\u7528leg_index:1\u3002\u6574\u7A0B\u6A21\u677F\u5217\u5168\u90E8\u53EF\u7528\u76EE\u6807\uFF0C\u6307\u5B9A\u8303\u56F4\u5219\u4EC5\u4FDD\u7559\u5BF9\u5E94\u76EE\u6807\uFF0C\u4E0D\u624B\u586B\u7968\u4EF7/\u4F9B\u5E94\u5546\u5355\u53F7\u3002\u8303\u56F4\u5DF2\u660E\u786E\u53EA\u8BF4\u660E\u540E\u63D0\u4EA4\uFF1B\u4E0D\u91CD\u65B0\u8BE2\u95EE\u6574\u7A0B\u9009\u62E9\u3002", next: null, recovery: [], interaction: { schema_version: "itpay.interaction.v1", stage: "input_required", input_templates: Object.fromEntries(Object.entries(directory.input_templates).map(([operation, input]) => [operation, fileInputTemplate(`itpay aftercare create --order ${orderID} --input-json <file> --json`, { ...input }, ["targets", "reason", "user_confirmed_scope"])])) } };
13725
+ // src/services/shared/agent_facts.generated.ts
13726
+ var truth = external_exports.union([external_exports.boolean(), external_exports.literal("unknown")]);
13727
+ var agentDisplaySchema = external_exports.object({
13728
+ version: external_exports.literal("itpay.agent.v1"),
13729
+ kind: external_exports.enum(["result", "selection", "confirmation", "handoff", "progress", "blocked", "error"]),
13730
+ state: external_exports.string(),
13731
+ summary: external_exports.string(),
13732
+ actions: external_exports.array(external_exports.object({ purpose: external_exports.string(), tool: external_exports.string(), arguments: external_exports.record(external_exports.unknown()), requires_confirmation: external_exports.boolean() }).strict()),
13733
+ acceptance: external_exports.enum(["accepted", "not_accepted", "unknown"]),
13734
+ references: external_exports.record(external_exports.string()),
13735
+ request_sent: external_exports.boolean().optional(),
13736
+ effects: external_exports.object({ persistent_task_created: truth, order_created: truth, inventory_held: truth, price_held: truth, payment_requested: truth, charged: truth, fulfilled: truth }).strict(),
13737
+ cost: external_exports.object({ classification: external_exports.enum(["public_free", "platform_subsidized", "included_entitlement", "user_paid", "unknown"]), settlement_state: external_exports.string(), actual_charge: external_exports.record(external_exports.unknown()).nullable(), wallet_debited: truth }).strict(),
13738
+ coverage: external_exports.record(external_exports.unknown()),
13739
+ freshness: external_exports.object({ observed_at: external_exports.string().nullable(), valid_until: external_exports.string().nullable(), from_cache: truth }).strict(),
13740
+ links: external_exports.array(external_exports.object({ kind: external_exports.string(), purpose: external_exports.string(), url: external_exports.string(), access: external_exports.literal("account_session"), expires_at: external_exports.string().nullable() }).strict()),
13741
+ recovery: external_exports.object({ kind: external_exports.enum(["read_original", "complete_account_step", "supply_missing_decision", "wait", "none"]), reason_code: external_exports.string().nullable() }).strict(),
13742
+ result: external_exports.record(external_exports.unknown()),
13743
+ untrusted_content: external_exports.literal(true)
13744
+ }).strict();
13745
+ function isRecord2(v) {
13746
+ return v !== null && typeof v === "object" && !Array.isArray(v);
13747
+ }
13748
+ __name(isRecord2, "isRecord");
13749
+ var object = /* @__PURE__ */ __name((v) => isRecord2(v) ? v : {}, "object");
13750
+ var text = /* @__PURE__ */ __name((v) => typeof v === "string" && v.length ? v : void 0, "text");
13751
+ var fact = /* @__PURE__ */ __name((v) => typeof v === "boolean" ? v : "unknown", "fact");
13752
+ var privateKeys = /* @__PURE__ */ new Set(["display_token", "complete_exchange_token", "receipt_token", "start_token", "poll_token", "access_token", "refresh_token", "session_token", "private_key", "authorization", "api_key", "provider_secret"]);
13753
+ function secretURL(value) {
13754
+ try {
13755
+ const u = new URL(value);
13756
+ return Boolean(u.username || u.password || [...u.searchParams.keys()].some((k) => privateKeys.has(k.toLowerCase()) || k.toLowerCase() === "token") || /(?:access_token|refresh_token|start_token|poll_token|display_token)=/i.test(u.hash));
13757
+ } catch {
13758
+ return false;
13759
+ }
13930
13760
  }
13931
- __name(railAftercareList, "railAftercareList");
13932
- function railAftercareEnvelope(view) {
13933
- const c = view.case;
13934
- const instruction = c.status === "awaiting_confirmation" ? "\u5C55\u793A\u5F53\u524D\u5177\u4F53\u6539\u7B7E\u65B9\u6848\u3001\u65E7\u65B0\u5BF9\u5E94\u3001\u5DEE\u4EF7\u548C\u6761\u4EF6\uFF1B\u65E7\u8D2D\u4E70\u59D4\u6258\u4E0D\u662F\u65B0\u65B9\u6848/\u8D39\u7528\u6279\u51C6\u3002\u6CA1\u6709\u771F\u5B9E\u56DE\u7B54\u4FDD\u6301false\u5E76\u7B49\u5F85\uFF1B\u672C\u8F6E\u8D39\u7528\u7531\u4EBA\u5DE5\u534F\u8C03\uFF0C\u6CA1\u6709\u81EA\u52A8\u652F\u4ED8\u94FE\u63A5\u3002" : c.status === "needs_input" ? "\u5C55\u793A\u7BA1\u7406\u5458\u8981\u6C42\u8865\u5145\u7684\u5185\u5BB9\uFF0C\u53EA\u8865\u7F3A\u5931\u4E8B\u5B9E\uFF1B\u4FDD\u7559\u539F\u7533\u8BF7\u8303\u56F4\u3002" : c.status === "completed" ? "\u4EBA\u5DE5\u53D7\u7406\u5DF2\u5B8C\u6210\uFF1B\u5206\u522B\u8BF4\u660E\u4F9B\u5E94\u5546\u6838\u9A8C\u7ED3\u679C\u4E0E\u5E73\u53F0\u9000\u6B3E\u91D1\u989D/\u72B6\u6001\u3002\u672A\u9000\u6BB5\u4EC5\u62A5\u544A\u6743\u5A01\u5DF2\u77E5\u4E8B\u5B9E\uFF0C\u4E0D\u4FDD\u8BC1\u4ECD\u53EF\u4E58\uFF1B\u4E0D\u6062\u590D\u5E73\u53F0\u5185\u5BB9\u8BBF\u95EE\u9501\u3002" : c.status === "processing" ? "\u539F\u7533\u8BF7\u6B63\u5728\u4EBA\u5DE5\u529E\u7406\u6216\u8D22\u52A1\u5904\u7406\u4E2D\uFF1B\u6CA1\u6709\u6700\u7EC8\u4E8B\u5B9E\u4E0D\u8BF4\u9000\u7968\u3001\u6539\u7B7E\u6216\u5230\u8D26\u6210\u529F\uFF0C\u4E0D\u91CD\u8BD5\u672A\u77E5\u8D44\u91D1\u3001\u4E0D\u53D6\u6D88\u5DF2\u53D1\u751F\u64CD\u4F5C\u3002" : ["cancelled", "rejected"].includes(c.status) ? "\u8BF4\u660E\u539F\u7533\u8BF7\u5DF2\u53D6\u6D88\u6216\u88AB\u62D2\u7EDD\u53CA\u539F\u56E0\uFF1B\u6CA1\u6709\u64A4\u9500\u5DF2\u53D1\u751F\u4F9B\u5E94\u5546\u64CD\u4F5C\uFF0C\u4E5F\u4E0D\u81EA\u52A8\u521B\u5EFA\u66FF\u4EE3\u8D2D\u4E70\u3002" : "\u5DF2\u63D0\u4EA4\u4EBA\u5DE5\u53D7\u7406\uFF0C\u5C1A\u672A\u786E\u8BA4\u4F9B\u5E94\u5546\u9000\u7968/\u6539\u7B7E\u6216\u94B1\u6B3E\u5230\u8D26\u3002\u5148\u4EA4\u4ED8\u7533\u8BF7\u72B6\u6001\u5165\u53E3\uFF0C\u518D\u6309\u7528\u6237\u610F\u613F\u67E5\u8BE2\u539F\u7533\u8BF7\uFF0C\u4E0D\u5FAA\u73AF\u8F6E\u8BE2\u3002";
13935
- const cancellation = view.can_cancel ? { cancel_template: fileInputTemplate(`itpay aftercare cancel ${c.case_id} --input-json <file> --json`, { expected_revision: c.revision, reason: "" }, ["reason"]) } : {};
13936
- const needsReply = ["awaiting_confirmation", "needs_input"].includes(c.status);
13937
- return { status: c.status, result: { ...view }, instruction, next: needsReply || ["completed", "cancelled", "rejected"].includes(c.status) ? null : { command: `itpay aftercare get ${c.case_id} --json`, reason: "\u6309\u7528\u6237\u8981\u6C42\u8BFB\u53D6\u540C\u4E00\u4EBA\u5DE5\u7533\u8BF7" }, recovery: [], ...needsReply || view.can_cancel ? { interaction: { schema_version: "itpay.interaction.v1", stage: c.status === "awaiting_confirmation" ? "consent_required" : "input_required", ...cancellation, ...needsReply ? { input_template: fileInputTemplate(`itpay aftercare respond ${c.case_id} --input-json <file> --json`, { expected_revision: c.revision, ...c.status === "awaiting_confirmation" ? { proposal_revision: c.proposal_revision, user_approved: false } : { additional_information: "" } }, c.status === "awaiting_confirmation" ? ["user_approved"] : ["additional_information"]) } : {} } } : {} };
13761
+ __name(secretURL, "secretURL");
13762
+ function publicData(value) {
13763
+ if (Array.isArray(value)) return value.map(publicData);
13764
+ if (value !== null && typeof value === "object") return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, privateKeys.has(key.toLowerCase()) ? { availability: "protected_transport_only" } : publicData(item)]));
13765
+ if (typeof value === "string") {
13766
+ if (secretURL(value)) return { availability: "secure_reference_required" };
13767
+ return value.replace(/https?:\/\/[^\s<>"']+/gi, (target2) => secretURL(target2) ? "[protected reference]" : target2);
13768
+ }
13769
+ return value;
13938
13770
  }
13939
- __name(railAftercareEnvelope, "railAftercareEnvelope");
13940
- async function railAftercareCreate(backend, config, orderID, raw) {
13941
- const parsed = inputSchema.safeParse(raw);
13942
- if (!parsed.success) throw new CommandContractError("rail_aftercare_input_invalid", "Aftercare input fields or genuine scope confirmation are missing", "Agent\u8BFB\u53D6\u5F53\u524D\u5B8C\u6574\u6A21\u677F\u4FEE\u6B63\u6280\u672F\u5B57\u6BB5\uFF1B\u53EA\u95EE\u7F3A\u5931\u7684\u771F\u5B9E\u8303\u56F4/\u6539\u7B7E\u610F\u5411\uFF0C\u4E0D\u8BA9\u7528\u6237\u586B\u6280\u672FJSON\u3002", [{ command: `itpay aftercare list --order ${orderID} --json`, reason: "\u8BFB\u53D6\u5F53\u524D\u884C\u7A0B\u3001\u76EE\u6807\u548C\u5B8C\u6574\u6A21\u677F" }]);
13943
- const value = parsed.data;
13944
- const change = value.change;
13945
- const input = { operation: value.operation, targets: value.targets, reason: value.reason, scope_revision: value.scope_revision, user_confirmed_scope: value.user_confirmed_scope, ...change ? { change: { constraints: change.constraints, ...change.travel_date !== void 0 ? { travel_date: change.travel_date } : {}, ...change.departure_after !== void 0 ? { departure_after: change.departure_after } : {}, ...change.arrival_before !== void 0 ? { arrival_before: change.arrival_before } : {}, ...change.seat_type !== void 0 ? { seat_type: change.seat_type } : {}, ...change.train_code !== void 0 ? { train_code: change.train_code } : {} } } : {} };
13946
- return railAftercareEnvelope(await backend.createRailAftercare(orderID, input, await operationID(config, `aftercare.create:${orderID}:${JSON.stringify(input)}`)));
13771
+ __name(publicData, "publicData");
13772
+ function accountEntryLink(value, allowedOrigins) {
13773
+ const v = text(value);
13774
+ if (!v) return;
13775
+ try {
13776
+ const u = new URL(v);
13777
+ if (!allowedOrigins.includes(u.origin) || u.username || u.password || u.search || u.hash || !/^\/(?:checkout|orders)\/[^/]+$/.test(u.pathname)) return;
13778
+ return u.href;
13779
+ } catch {
13780
+ return;
13781
+ }
13947
13782
  }
13948
- __name(railAftercareCreate, "railAftercareCreate");
13783
+ __name(accountEntryLink, "accountEntryLink");
13784
+ function presentAgent(value, options) {
13785
+ const raw = object(value), service = object(raw.service);
13786
+ const appliedRoot = object(service.result);
13787
+ const applied = Object.keys(object(appliedRoot.original_result)).length ? object(appliedRoot.original_result) : appliedRoot;
13788
+ const checkout = Object.keys(object(service.checkout)).length ? object(service.checkout) : object(raw.checkout), handoff = applied.checkout_id ? applied : object(service.handoff);
13789
+ const purchase = object(raw.review), sourceEffects = object(raw.effects);
13790
+ const purchaseProgress = raw.completed_stage !== void 0 || raw.poll_after_ms !== void 0 || raw.auto_wait_remaining_ms !== void 0 ? { status: raw.status ?? null, completed_stage: raw.completed_stage ?? null, poll_after_ms: raw.poll_after_ms ?? null, auto_wait_remaining_ms: raw.auto_wait_remaining_ms ?? null } : void 0;
13791
+ const refs = { ...options.originalReferences };
13792
+ const refKeys = ["run_id", "intent_id", "operation_id", "publication_id", "request_ref", "service_execution_id", "source_service_execution_id", "checkout_id", "order_id", "case_id", "result_ref"];
13793
+ for (const source of [raw, service, applied, handoff, checkout, object(object(raw.result).case)]) for (const key of refKeys) {
13794
+ const v = text(source[key]);
13795
+ if (v) refs[key] = v;
13796
+ }
13797
+ const error = object(raw.error), summary = object(service.summary);
13798
+ let state = text(checkout.status) ?? text(applied.state) ?? text(service.state) ?? text(raw.execution_state) ?? text(raw.status) ?? text(object(object(raw.result).case).status) ?? "unknown";
13799
+ const acceptance = raw.accepted === false ? "not_accepted" : raw.accepted === true || text(raw.run_id) || text(raw.service_execution_id) ? "accepted" : text(raw.intent_id) && !text(raw.run_id) ? "not_accepted" : "unknown";
13800
+ const paymentReceived = ["payment_succeeded", "completed", "refunded"].includes(text(checkout.status) ?? "");
13801
+ const links = [];
13802
+ const entry = object(raw.official_entry ?? object(raw.checkout).official_entry);
13803
+ const candidates = [...Array.isArray(handoff.links) ? handoff.links : [], ...entry.url ? [entry] : []];
13804
+ for (const candidate of candidates) {
13805
+ const c = object(candidate);
13806
+ if (c.access !== "account_session" && handoff.handoff_access !== "account_session") continue;
13807
+ const url = accountEntryLink(c.url, options.allowedOrigins);
13808
+ if (url && !links.some((l) => l.url === url)) links.push({ kind: text(c.kind) ?? "official_checkout", purpose: text(c.purpose) ?? "checkout", url, access: "account_session", expires_at: text(c.expires_at) ?? text(handoff.expires_at) ?? null });
13809
+ }
13810
+ if (["expired", "cancelled", "failed"].includes(state)) links.length = 0;
13811
+ let kind = Object.keys(error).length ? "error" : ["queued", "running", "in_flight", "processing", "started"].includes(state) ? "progress" : Object.keys(purchase).length ? "confirmation" : links.length ? "handoff" : state === "blocked" ? "blocked" : "result";
13812
+ if (state === "unknown" || state === "unavailable") kind = "error";
13813
+ if (paymentReceived) state = checkout.status === "refunded" ? "refunded" : "payment_received";
13814
+ const settlement = text(raw.settlement_state) ?? "unknown";
13815
+ const costClass = object(raw.cost).classification;
13816
+ const classification = costClass === "public_free" || costClass === "platform_subsidized" || costClass === "included_entitlement" || costClass === "user_paid" ? costClass : "unknown";
13817
+ const code = text(error.code) ?? text(summary.error_code) ?? text(applied.reason_code);
13818
+ const reason = code && /^[a-zA-Z0-9_.:-]{1,128}$/.test(code) ? code : null;
13819
+ const result = object(publicData({ ...purchaseProgress ? { purchase_progress: purchaseProgress } : {}, ...Object.keys(purchase).length ? { purchase_review: purchase } : {}, ...Object.keys(error).length ? { error } : {}, ...service.summary !== void 0 ? { summary: service.summary } : {}, ...service.actions !== void 0 ? { available_choices: service.actions } : {}, ...service.result !== void 0 ? { service_result: service.result } : {}, ...raw.result !== void 0 ? { content: raw.result } : {}, ...Object.keys(checkout).length ? { checkout } : {}, ...raw.effects !== void 0 ? { preparation_effects: raw.effects } : {} }));
13820
+ return agentDisplaySchema.parse({
13821
+ version: "itpay.agent.v1",
13822
+ kind,
13823
+ state,
13824
+ summary: state === "unknown" ? "\u539F\u4EFB\u52A1\u72B6\u6001\u5C1A\u672A\u786E\u8BA4" : kind === "progress" ? "\u539F\u4EFB\u52A1\u5904\u7406\u4E2D" : kind === "handoff" ? "\u8BF7\u767B\u5F55\u539F\u8D26\u53F7\u529E\u7406" : state === "payment_received" ? "\u4ED8\u6B3E\u5DF2\u786E\u8BA4\uFF0C\u5C65\u7EA6\u4EE5\u539F\u8BA2\u5355\u4E8B\u5B9E\u4E3A\u51C6" : "\u5F53\u524D\u4E8B\u5B9E\u89C1 result",
13825
+ actions: [],
13826
+ acceptance,
13827
+ references: refs,
13828
+ ...typeof raw.request_sent === "boolean" ? { request_sent: raw.request_sent } : {},
13829
+ effects: { persistent_task_created: fact(sourceEffects.persistent_task_created), order_created: fact(sourceEffects.order_created), inventory_held: fact(sourceEffects.inventory_held), price_held: fact(sourceEffects.price_held), payment_requested: fact(sourceEffects.payment_requested), charged: paymentReceived ? true : fact(sourceEffects.charged), fulfilled: fact(sourceEffects.fulfilled) },
13830
+ cost: { classification, settlement_state: settlement, actual_charge: raw.actual_charge === void 0 ? null : object(publicData(raw.actual_charge)), wallet_debited: ["captured", "partially_refunded", "refunded"].includes(settlement) ? true : ["free", "reserved", "released"].includes(settlement) ? false : "unknown" },
13831
+ coverage: object(publicData(applied.coverage ?? summary.coverage ?? raw.coverage)),
13832
+ freshness: { observed_at: text(applied.observed_at) ?? text(summary.observed_at) ?? text(raw.updated_at) ?? null, valid_until: text(applied.expires_at) ?? text(summary.expires_at) ?? null, from_cache: fact(applied.from_cache ?? summary.from_cache) },
13833
+ links,
13834
+ recovery: { kind: kind === "confirmation" ? "supply_missing_decision" : links.length ? "complete_account_step" : refs.run_id || refs.service_execution_id ? "read_original" : "none", reason_code: reason },
13835
+ result,
13836
+ untrusted_content: true
13837
+ });
13838
+ }
13839
+ __name(presentAgent, "presentAgent");
13840
+
13841
+ // src/render/telegram.ts
13842
+ function buttonsFor(plan) {
13843
+ if (plan.kind === "payment_qr" && plan.paymentIntentID) {
13844
+ return [
13845
+ { label: "\u652F\u4ED8\u9047\u5230\u95EE\u9898 / \u5237\u65B0", kind: "callback", intent: "refresh_payment_qr", ref: plan.paymentIntentID },
13846
+ { label: "\u6211\u5DF2\u4ED8\u6B3E\uFF0C\u67E5\u8BE2\u72B6\u6001", kind: "callback", intent: "check_payment_status", ref: plan.paymentIntentID }
13847
+ ];
13848
+ }
13849
+ if (plan.kind === "auth_qr" && plan.checkoutID) {
13850
+ return [
13851
+ { label: "\u6253\u5F00\u6388\u6743\u9875\u9762", kind: "url", url: plan.url },
13852
+ { label: "\u67E5\u8BE2\u6388\u6743\u72B6\u6001", kind: "callback", intent: "check_checkout_status", ref: plan.checkoutID }
13853
+ ];
13854
+ }
13855
+ return [
13856
+ { label: "\u{1F4F1} \u624B\u673A\u70B9\u8FD9\u513F\u652F\u4ED8", kind: "url", url: plan.url },
13857
+ ...plan.checkoutID ? [{ label: "\u{1F4CB} \u5DF2\u6388\u6743\u7ED9\u6211\u8BFB", kind: "callback", intent: "grant_confirmed", ref: plan.checkoutID }] : []
13858
+ ];
13859
+ }
13860
+ __name(buttonsFor, "buttonsFor");
13861
+ function nativeButton(button) {
13862
+ if (button.kind === "url") {
13863
+ return { label: button.label, url: button.url ?? "" };
13864
+ }
13865
+ const value = button.intent === "check_checkout_status" ? `itp:checkout:${button.ref ?? ""}` : `itp:${button.intent ?? "callback"}:${button.ref ?? ""}`;
13866
+ return { label: button.label, value };
13867
+ }
13868
+ __name(nativeButton, "nativeButton");
13869
+ function renderTelegram(plan, options) {
13870
+ const out = options.output ?? ((line) => process.stdout.write(line));
13871
+ const agentAction = buildOpenClawTelegramAction(plan, options.target);
13872
+ const presentation = agentAction.arguments.presentation;
13873
+ const media = collectTelegramMedia(plan);
13874
+ const text2 = agentAction.arguments.message;
13875
+ const openclawMessage = {
13876
+ command: [
13877
+ "openclaw",
13878
+ "message",
13879
+ "send",
13880
+ "--channel",
13881
+ "telegram",
13882
+ "--target",
13883
+ options.target,
13884
+ "--message",
13885
+ text2,
13886
+ ...media.length > 0 ? ["--media", media[0].url] : [],
13887
+ "--presentation",
13888
+ JSON.stringify(presentation)
13889
+ ],
13890
+ // Keep the same Checkout visible if native buttons are unavailable.
13891
+ if_unavailable: "If `openclaw message send` is unavailable, send the same QR media and Checkout URL as ordinary Telegram content, report that inline buttons are unavailable, and stop. Do not create another Checkout."
13892
+ };
13893
+ out(JSON.stringify({ presentation, agent_action: agentAction, openclaw_message: openclawMessage }, null, 2) + "\n");
13894
+ }
13895
+ __name(renderTelegram, "renderTelegram");
13896
+ function buildOpenClawTelegramAction(plan, target2) {
13897
+ const buttons = buttonsFor(plan).map(nativeButton);
13898
+ const media = collectTelegramMedia(plan);
13899
+ const message = plan.kind === "payment_qr" ? `ItPay payment QR \u2014 ${plan.summary}` : plan.kind === "auth_qr" ? `ItPay auth required \u2014 ${plan.summary}` : `ItPay checkout QR \u2014 ${plan.summary}`;
13900
+ const presentation = {
13901
+ blocks: [{ type: "buttons", buttons }]
13902
+ };
13903
+ const nativeTarget = target2.trim().replace(/^telegram:/i, "");
13904
+ return {
13905
+ tool: "message",
13906
+ arguments: {
13907
+ action: "send",
13908
+ channel: "telegram",
13909
+ target: nativeTarget,
13910
+ message,
13911
+ ...media[0]?.url ? { media: media[0].url } : {},
13912
+ presentation
13913
+ }
13914
+ };
13915
+ }
13916
+ __name(buildOpenClawTelegramAction, "buildOpenClawTelegramAction");
13917
+ function collectTelegramMedia(plan) {
13918
+ const media = (plan.platform.media ?? []).map((item) => ({
13919
+ url: item.url,
13920
+ mimeType: item.mimeType ?? "image/png"
13921
+ }));
13922
+ if (plan.kind === "payment_qr" || media.length === 0) {
13923
+ media.unshift({
13924
+ url: plan.preferredQRSources.find((src) => src.length > 0) ?? plan.url,
13925
+ mimeType: "image/png"
13926
+ });
13927
+ }
13928
+ return media;
13929
+ }
13930
+ __name(collectTelegramMedia, "collectTelegramMedia");
13931
+
13932
+ // src/render/checkout_handoff.ts
13933
+ function shouldPrepareLocalCheckoutImage(platform2) {
13934
+ return platform2 === "markdown";
13935
+ }
13936
+ __name(shouldPrepareLocalCheckoutImage, "shouldPrepareLocalCheckoutImage");
13937
+ function isWorkBuddyPlainChat(agentType, platform2) {
13938
+ return agentType?.trim().toLowerCase() === "workbuddy" && platform2 === "plain_chat";
13939
+ }
13940
+ __name(isWorkBuddyPlainChat, "isWorkBuddyPlainChat");
13941
+ function isZCodePlainChat(agentType, platform2) {
13942
+ return agentType?.trim().toLowerCase() === "zcode" && platform2 === "plain_chat";
13943
+ }
13944
+ __name(isZCodePlainChat, "isZCodePlainChat");
13945
+ function isLinkOnlyBrowserAgent(agentType, platform2) {
13946
+ return isWorkBuddyPlainChat(agentType, platform2) || isZCodePlainChat(agentType, platform2);
13947
+ }
13948
+ __name(isLinkOnlyBrowserAgent, "isLinkOnlyBrowserAgent");
13949
+ function buildWorkBuddyPresentFilesAction(url) {
13950
+ return {
13951
+ tool: "present_files",
13952
+ arguments: { files: [url] }
13953
+ };
13954
+ }
13955
+ __name(buildWorkBuddyPresentFilesAction, "buildWorkBuddyPresentFilesAction");
13956
+ function hasCompleteCheckoutTokens(url) {
13957
+ if (!url) {
13958
+ return false;
13959
+ }
13960
+ try {
13961
+ const parsed = new URL(url);
13962
+ return Boolean(parsed.searchParams.get("display_token") && parsed.searchParams.get("complete_exchange_token"));
13963
+ } catch {
13964
+ return false;
13965
+ }
13966
+ }
13967
+ __name(hasCompleteCheckoutTokens, "hasCompleteCheckoutTokens");
13968
+ function buildCheckoutHandoff(input) {
13969
+ const url = input.plan?.localSimulation && input.mobileUrl && hasCompleteCheckoutTokens(input.mobileUrl) ? input.mobileUrl : input.url;
13970
+ const handoff = { url, ...input.plan?.localSimulation ? { environment: "local_simulation", query: "live", transactions: "simulated" } : {} };
13971
+ const mobileUrl = !input.plan?.localSimulation && hasCompleteCheckoutTokens(input.mobileUrl) ? input.mobileUrl : void 0;
13972
+ if (mobileUrl) {
13973
+ handoff.mobile_url = mobileUrl;
13974
+ }
13975
+ const workBuddyAction = isWorkBuddyPlainChat(input.agentType, input.platform);
13976
+ if (workBuddyAction) {
13977
+ handoff.agent_action = buildWorkBuddyPresentFilesAction(url);
13978
+ }
13979
+ if (input.platform === "markdown") {
13980
+ if (input.localPath) handoff.qr_local_path = input.localPath;
13981
+ if (input.markdown) handoff.markdown = input.markdown;
13982
+ } else if (input.platform === "plain_chat" && input.qrImageURL && !isLinkOnlyBrowserAgent(input.agentType, input.platform)) {
13983
+ handoff.qr_image_url = input.qrImageURL;
13984
+ } else if (input.platform === "telegram" && input.qrImageURL) {
13985
+ handoff.qr_image_url = input.qrImageURL;
13986
+ }
13987
+ if (input.agentType?.trim().toLowerCase() === "openclaw" && input.platform === "telegram" && input.plan && input.target) {
13988
+ handoff.agent_action = buildOpenClawTelegramAction(input.plan, input.target);
13989
+ }
13990
+ return {
13991
+ handoff,
13992
+ instruction: input.plan?.localSimulation ? `\u672C\u5730\u5B9E\u9A8C\uFF1A\u94C1\u8DEF\u4E0E\u5730\u56FE\u67E5\u8BE2\u771F\u5B9E\uFF0C\u6388\u6743\u3001\u901A\u77E5\u548C\u4EA4\u6613\u6A21\u62DF\uFF0C\u4E0D\u4F1A\u6263\u6B3E\u3002\u5728\u672C\u673A\u6253\u5F00 handoff.url \u6A21\u62DF\u4ED8\u6B3E\u5165\u53E3\uFF0C\u91D1\u989D ${input.amount}\uFF1B\u4EC5\u672C\u673A\u684C\u9762\u53EF\u8FBE\u3002${workBuddyAction ? "\u6309 handoff.agent_action \u539F\u6837\u6253\u5F00\u4E00\u6B21\u3002" : "\u5C55\u793A\u539F\u5165\u53E3\u3002"}\u7B49\u5F85\u7528\u6237\u64CD\u4F5C\u540E\u8BFB\u53D6\u540C\u4E00 Checkout\uFF1B\u4E0D\u521B\u5EFA\u66FF\u4EE3\u8BA2\u5355\uFF0C\u7528\u6237\u58F0\u660E\u4E0D\u8BC1\u660E\u6A21\u62DF\u4ED8\u6B3E\u5DF2\u786E\u8BA4\u3002` : `\u5148\u5C55\u793A\u5B98\u65B9\u5165\u53E3\uFF0C\u518D\u505A\u975E\u5FC5\u8981\u8BB0\u5FC6\u6216\u65E5\u5FD7\uFF1B\u4FDD\u7559\u5FC5\u9700\u5B89\u5168\u68C0\u67E5\u548C\u5BBF\u4E3B\u6743\u9650\u3002${checkoutHandoffInstruction(input.agentType, input.platform, input.amount, Boolean(mobileUrl))}`
13993
+ };
13994
+ }
13995
+ __name(buildCheckoutHandoff, "buildCheckoutHandoff");
13996
+ function checkoutHandoffInstruction(agentType, platform2, amount, hasMobileLink) {
13997
+ if (isWorkBuddyPlainChat(agentType, platform2)) {
13998
+ const mobileSentence = hasMobileLink ? "\uFF0C\u7136\u540E\u628A handoff.mobile_url \u4F5C\u4E3A\u53EF\u70B9\u51FB\u94FE\u63A5\u53D1\u7ED9\u7528\u6237\uFF0C\u8BF4\u660E\u201C\u624B\u673A\u7AEF\u70B9\u5F00\u53EF\u76F4\u63A5\u8DF3\u8F6C\u652F\u4ED8\u5B9D\u6216\u5FAE\u4FE1\u652F\u4ED8\uFF1B\u5C0F\u7A0B\u5E8F\u5185\u6253\u4E0D\u5F00\u65F6\u590D\u5236\u5230\u624B\u673A\u6D4F\u89C8\u5668\u6253\u5F00\u5373\u53EF\u201D" : "";
13999
+ const failLinks = hasMobileLink ? "\u53D1\u9001 handoff.url \u4E0E handoff.mobile_url" : "\u53D1\u9001\u539F\u59CB handoff.url";
14000
+ return `Backend \u5C1A\u672A\u786E\u8BA4\u4ED8\u6B3E\u3002\u82E5\u5F53\u524D\u53EF\u7528 present_files\uFF0C\u6309 handoff.agent_action \u539F\u6837\u6267\u884C\u4E00\u6B21\uFF1B\u4E0D\u53EF\u7528\u5219\u5F53\u8F6E\u76F4\u63A5\u5C55\u793A\u539F\u94FE\u63A5\uFF0C\u5728\u53F3\u4FA7\u6253\u5F00 handoff.url\uFF1B\u5DE5\u5177\u6210\u529F\u6216\u76F4\u63A5\u5C55\u793A\u94FE\u63A5\u540E\u8BF4\u660E\u91D1\u989D ${amount}${mobileSentence}\uFF0C\u7136\u540E\u505C\u6B62\u7B49\u5F85\u3002\u82E5\u5DE5\u5177\u5931\u8D25\uFF0C\u53EA${failLinks}\uFF0C\u62A5\u544A\u672A\u81EA\u52A8\u6253\u5F00\u5E76\u505C\u6B62\u3002\u4E0D\u8981\u7528 present_files \u6253\u5F00\u672C\u5730\u6587\u4EF6\u6216\u4E8C\u7EF4\u7801 PNG\uFF0C\u4E0D\u8981\u4E0B\u8F7D\u6216\u91CD\u5EFA\u4E8C\u7EF4\u7801\uFF0C\u4E0D\u8981\u8C03\u7528 pay\uFF0C\u4E0D\u8981\u521B\u5EFA\u65B0 Checkout\u3001Payment Intent \u6216 Execution\u3002\u53EA\u6709\u7528\u6237\u660E\u786E\u8868\u793A\u5DF2\u4ED8\u6B3E\u6216\u8981\u6C42\u67E5\u8BE2\u72B6\u6001\u65F6\uFF0C\u624D\u6267\u884C next.command\uFF1B\u7528\u6237\u7684\u8BDD\u4E0D\u662F\u4ED8\u6B3E\u6210\u529F\u8BC1\u660E\u3002`;
14001
+ }
14002
+ if (isZCodePlainChat(agentType, platform2)) {
14003
+ const mobileSentence = hasMobileLink ? "\uFF0C\u5E76\u628A handoff.mobile_url \u53D1\u7ED9\u7528\u6237\u5907\u7528\uFF08\u624B\u673A\u7AEF\u70B9\u5F00\u53EF\u76F4\u63A5\u8DF3\u8F6C\u652F\u4ED8\u5B9D\u6216\u5FAE\u4FE1\u652F\u4ED8\uFF09" : "";
14004
+ const fallbackLinks = hasMobileLink ? "\u540C\u4E00\u4E2A\u53EF\u70B9\u51FB handoff.url \u4E0E handoff.mobile_url" : "\u540C\u4E00\u4E2A\u53EF\u70B9\u51FB handoff.url";
14005
+ return `Backend \u5C1A\u672A\u786E\u8BA4\u4ED8\u6B3E\u3002\u7ACB\u5373\u7528 ZCode \u5185\u7F6E\u6D4F\u89C8\u5668\u6253\u5F00 handoff.url\uFF0C\u8BA9\u7528\u6237\u5B8C\u6210\u4ED8\u6B3E\uFF1B\u786E\u8BA4\u5DF2\u53D1\u8D77\u6253\u5F00\u540E\u8BF4\u660E\u91D1\u989D ${amount}${mobileSentence}\uFF0C\u7136\u540E\u505C\u6B62\u7B49\u5F85\u3002\u5DE5\u5177\u4E0D\u53EF\u7528\u65F6\u76F4\u63A5\u5C55\u793A\u94FE\u63A5\uFF0C\u4E0D\u8981\u4E0B\u8F7D\u3001\u89E3\u6790\u6216\u91CD\u5EFA\u4E8C\u7EF4\u7801\uFF0C\u4E0D\u8981\u521B\u5EFA\u65B0 Checkout\u3001Payment Intent \u6216 Execution\u3002\u53EA\u6709\u5185\u7F6E\u6D4F\u89C8\u5668\u660E\u786E\u4E0D\u53EF\u7528\u65F6\uFF0C\u624D\u5C55\u793A${fallbackLinks}\u3002\u53EA\u6709\u7528\u6237\u660E\u786E\u8868\u793A\u5DF2\u4ED8\u6B3E\u6216\u8981\u6C42\u67E5\u8BE2\u72B6\u6001\u65F6\uFF0C\u624D\u6267\u884C next.command\uFF1B\u7528\u6237\u7684\u8BDD\u4E0D\u662F\u4ED8\u6B3E\u6210\u529F\u8BC1\u660E\u3002`;
14006
+ }
14007
+ if (agentType?.trim().toLowerCase() === "doubao-work" && platform2 === "plain_chat") {
14008
+ const directLink = hasMobileLink ? "handoff.mobile_url" : "handoff.url";
14009
+ const directLabel = hasMobileLink ? "\u624B\u673A\u76F4\u63A5\u6253\u5F00\u6536\u94F6\u53F0\uFF08\u53EF\u8DF3\u8F6C\u652F\u4ED8\u5B9D/\u5FAE\u4FE1\uFF09" : "\u624B\u673A\u76F4\u63A5\u6253\u5F00\u6536\u94F6\u53F0";
14010
+ return `Backend \u5C1A\u672A\u786E\u8BA4\u4ED8\u6B3E\u3002\u5728\u5F53\u524D\u8C46\u5305\u5DE5\u4F5C\u5BF9\u8BDD\u4E2D\u5C55\u793A\u4E24\u4E2A\u6709\u6807\u7B7E\u7684\u5B98\u65B9\u5165\u53E3\uFF1A\u5C06 ${directLink} \u6807\u4E3A\u201C${directLabel}\u201D\uFF0C\u5C06 handoff.qr_image_url \u6807\u4E3A\u201C\u4E8C\u7EF4\u7801\u56FE\u7247\uFF08\u4FDD\u5B58\u6216\u7528\u53E6\u4E00\u53F0\u8BBE\u5907\u626B\u7801\uFF09\u201D\u3002\u8BF4\u660E\u91D1\u989D ${amount} \u540E\u505C\u6B62\u7B49\u5F85\u3002\u4E0D\u8981\u89E3\u6790\u6216\u5355\u72EC\u8F93\u51FA URL credential\uFF0C\u4E0D\u8981\u4E0B\u8F7D\u6216\u91CD\u5EFA\u4E8C\u7EF4\u7801\uFF0C\u4E0D\u8981\u8C03\u7528 pay\uFF0C\u4E0D\u8981\u521B\u5EFA\u65B0 Checkout\u3001Payment Intent \u6216 Execution\u3002\u53EA\u6709\u7528\u6237\u660E\u786E\u8868\u793A\u5DF2\u4ED8\u6B3E\u6216\u8981\u6C42\u67E5\u8BE2\u72B6\u6001\u65F6\uFF0C\u624D\u6267\u884C next.command\uFF1B\u7528\u6237\u7684\u8BDD\u4E0D\u662F\u4ED8\u6B3E\u6210\u529F\u8BC1\u660E\u3002`;
14011
+ }
14012
+ if (platform2 === "markdown") {
14013
+ const mobileSentence = hasMobileLink ? "\uFF0C\u5E76\u9644 handoff.mobile_url \u4F9B\u624B\u673A\u7AEF\u70B9\u51FB\u76F4\u8FBE\u652F\u4ED8" : "";
14014
+ return `Backend \u5C1A\u672A\u786E\u8BA4\u4ED8\u6B3E\u3002\u628A handoff.markdown \u539F\u6837\u53D1\u9001\u5230\u5F53\u524D\u684C\u9762\u5BF9\u8BDD\uFF0C\u786E\u8BA4\u4E8C\u7EF4\u7801\u3001\u4ED8\u6B3E\u94FE\u63A5\u548C\u91D1\u989D ${amount} \u5747\u5DF2\u5B9E\u9645\u5BF9\u7528\u6237\u53EF\u89C1${mobileSentence}\uFF0C\u7136\u540E\u505C\u6B62\u7B49\u5F85\u3002\u4E0D\u8981\u521B\u5EFA\u65B0 Checkout\u3001Payment Intent \u6216 Execution\uFF1B\u53EA\u6709\u7528\u6237\u660E\u786E\u8868\u793A\u5DF2\u4ED8\u6B3E\u6216\u8981\u6C42\u67E5\u8BE2\u72B6\u6001\u65F6\uFF0C\u624D\u6267\u884C next.command\uFF1B\u7528\u6237\u7684\u8BDD\u4E0D\u662F\u4ED8\u6B3E\u6210\u529F\u8BC1\u660E\u3002`;
14015
+ }
14016
+ if (platform2 === "terminal") {
14017
+ const mobileSentence = hasMobileLink ? "\uFF0C\u5E76\u5C55\u793A handoff.mobile_url \u4F9B\u624B\u673A\u7AEF\u70B9\u51FB\u76F4\u8FBE\u652F\u4ED8" : "";
14018
+ return `Backend \u5C1A\u672A\u786E\u8BA4\u4ED8\u6B3E\u3002\u5728\u7528\u6237\u53EF\u89C1\u7EC8\u7AEF\u5C55\u793A\u5F53\u524D Checkout \u7684\u4E8C\u7EF4\u7801\u3001handoff.url \u548C\u91D1\u989D ${amount}${mobileSentence}\uFF0C\u7136\u540E\u505C\u6B62\u7B49\u5F85\u3002\u4E0D\u8981\u521B\u5EFA\u65B0 Checkout\u3001Payment Intent \u6216 Execution\uFF1B\u53EA\u6709\u7528\u6237\u660E\u786E\u8868\u793A\u5DF2\u4ED8\u6B3E\u6216\u8981\u6C42\u67E5\u8BE2\u72B6\u6001\u65F6\uFF0C\u624D\u6267\u884C next.command\uFF1B\u7528\u6237\u7684\u8BDD\u4E0D\u662F\u4ED8\u6B3E\u6210\u529F\u8BC1\u660E\u3002`;
14019
+ }
14020
+ if (agentType?.trim().toLowerCase() === "openclaw" && platform2 === "telegram") {
14021
+ const failLinks = hasMobileLink ? "handoff.qr_image_url\u3001\u91D1\u989D\u3001handoff.url \u4E0E handoff.mobile_url" : "handoff.qr_image_url\u3001\u91D1\u989D\u548C handoff.url";
14022
+ return `Backend \u5C1A\u672A\u786E\u8BA4\u4ED8\u6B3E\u6216\u6388\u6743\u72B6\u6001\u3002\u82E5\u5F53\u524D\u5DF2\u6709\u53EF\u7528 OpenClaw \u539F\u751F message tool\uFF0C\u4E25\u683C\u6309 handoff.agent_action.tool \u548C handoff.agent_action.arguments \u539F\u6837\u6267\u884C\uFF1B\u5B83\u4F1A\u53D1\u9001\u91D1\u989D ${amount}\u3001\u4E8C\u7EF4\u7801\u3001\u{1F4F1} \u624B\u673A\u70B9\u8FD9\u513F\u652F\u4ED8\u548C \u{1F4CB} \u5DF2\u6388\u6743\u7ED9\u6211\u8BFB\u3002\u4E0D\u5F97\u6539\u5199 presentation\u3001\u6362\u7528\u5176\u4ED6\u6D88\u606F\u5DE5\u5177\u3001\u62C6\u5F00\u6309\u94AE\u53D1\u9001\u6216\u7528\u666E\u901A\u56DE\u590D\u58F0\u79F0\u6309\u94AE\u5DF2\u7ECF\u53D1\u9001\u3002\u5DE5\u5177\u4E0D\u53EF\u7528\u65F6\u5F53\u8F6E\u76F4\u63A5\u5C55\u793A\u5DF2\u6709\u5B98\u65B9\u94FE\u63A5\uFF0C\u4E0D\u7814\u7A76\u6216\u5B89\u88C5\u5DE5\u5177\uFF1B\u5DE5\u5177\u6210\u529F\u6216\u5C55\u793A\u94FE\u63A5\u540E\u505C\u6B62\u7B49\u5F85\u3002\u6536\u5230 callback_data "itp:grant_confirmed:<checkout_id>" \u65F6\uFF0C\u8868\u793A\u7528\u6237\u58F0\u660E\u5DF2\u5728\u6536\u94F6\u53F0\u6388\u6743\u8BFB\u53D6\uFF1B\u7ACB\u5373\u6267\u884C next.command \u67E5\u8BE2\u540C\u4E00 Checkout\uFF0C\u518D\u53EA\u6267\u884C Backend \u8FD4\u56DE\u7684 next.command \u8FDB\u5165\u540C\u4E00 Execution \u7684 grant \u6D41\u7A0B\u3002\u8BE5 callback \u4E0D\u8BC1\u660E\u4ED8\u6B3E\u6210\u529F\u6216 grant \u5DF2\u751F\u6548\uFF1BBackend \u672A\u8FD4\u56DE grant_active \u524D\u4E0D\u5F97\u8BFB\u53D6\u6216\u731C\u6D4B\u7ED3\u679C\u3002\u82E5\u539F\u751F message tool \u660E\u786E\u5931\u8D25\u6216\u5F53\u524D Telegram \u672A\u542F\u7528 inline buttons\uFF0C\u53EA\u53D1\u9001\u73B0\u6709 ${failLinks}\uFF0C\u62A5\u544A\u6309\u94AE\u4E0D\u53EF\u7528\u5E76\u505C\u6B62\uFF1B\u4E0D\u8981\u521B\u5EFA\u65B0\u7684 Checkout\u3001Payment Intent \u6216 Execution\u3002`;
14023
+ }
14024
+ const urlList = hasMobileLink ? "handoff.url\u3001handoff.mobile_url\uFF08\u624B\u673A\u7AEF\u70B9\u51FB\u76F4\u8FBE\u652F\u4ED8\uFF09\u548C\u53EF\u7528\u7684 handoff.qr_image_url" : "handoff.url \u548C\u53EF\u7528\u7684 handoff.qr_image_url";
14025
+ return `Backend \u5C1A\u672A\u786E\u8BA4\u4ED8\u6B3E\u3002\u628A ${urlList} \u5B9E\u9645\u53D1\u9001\u5230\u5F53\u524D\u4F1A\u8BDD\uFF0C\u8BF4\u660E\u91D1\u989D ${amount}\uFF0C\u7136\u540E\u505C\u6B62\u7B49\u5F85\u3002\u4E0D\u8981\u521B\u5EFA\u65B0 Checkout\u3001Payment Intent \u6216 Execution\uFF1B\u53EA\u6709\u7528\u6237\u660E\u786E\u8868\u793A\u5DF2\u4ED8\u6B3E\u6216\u8981\u6C42\u67E5\u8BE2\u72B6\u6001\u65F6\uFF0C\u624D\u6267\u884C next.command\uFF1B\u7528\u6237\u7684\u8BDD\u4E0D\u662F\u4ED8\u6B3E\u6210\u529F\u8BC1\u660E\u3002`;
14026
+ }
14027
+ __name(checkoutHandoffInstruction, "checkoutHandoffInstruction");
14028
+
14029
+ // src/commands/checkout_handoff.ts
14030
+ var payableStates = ["draft", "quote_bound", "auth_required", "payment_required"];
14031
+ function assertCheckoutCreation(checkout, cartID, sourceExecutionID) {
14032
+ const current = checkout.checkout;
14033
+ if (!current.checkout_id || current.cart_id !== cartID || !payableStates.includes(current.status) || !checkout.display_token) {
14034
+ throw checkoutNotPayable(current, cartID, sourceExecutionID, false);
14035
+ }
14036
+ }
14037
+ __name(assertCheckoutCreation, "assertCheckoutCreation");
14038
+ function assertCheckoutPayable(checkout, authoritative, cartID, sourceExecutionID) {
14039
+ const current = authoritative?.checkout ?? checkout.checkout;
14040
+ const deadlineClosed = authoritative?.payment_remaining_seconds === 0 || current.expires_at !== void 0 && (!authoritative?.server_now || Date.parse(current.expires_at) <= Date.parse(authoritative.server_now));
14041
+ if (current.cart_id && current.cart_id !== cartID || !payableStates.includes(current.status) || authoritative?.payment_intents.some((intent) => !["failed", "cancelled", "expired"].includes(intent.status)) || deadlineClosed || !checkout.display_token) {
14042
+ throw checkoutNotPayable(current, cartID, sourceExecutionID, deadlineClosed);
14043
+ }
14044
+ }
14045
+ __name(assertCheckoutPayable, "assertCheckoutPayable");
14046
+ function checkoutNotPayable(current, cartID, sourceExecutionID, deadlineClosed) {
14047
+ return new CommandContractError(
14048
+ "checkout_not_payable",
14049
+ "original checkout is not a current payable entry",
14050
+ "\u539FCheckout\u4E0D\u53EF\u4F5C\u4E3A\u65B0\u4ED8\u6B3E\u5165\u53E3\uFF1B\u6838\u5BF9\u539F\u8BA2\u5355\u3002\u8FC7\u671F\u4E0D\u7EED\u671F\uFF0C\u4ED8\u6B3E\u5904\u7406\u4E2D\u6216\u672A\u77E5\u4E0D\u91CD\u653E\uFF0C\u4E0D\u6362\u8D2D\u7269\u8F66\u6216\u5E42\u7B49\u952E\u521B\u5EFA\u66FF\u4EE3\u8D2D\u4E70\u3002",
14051
+ sourceExecutionID ? [{ command: `itpay services next ${sourceExecutionID} --json`, reason: "\u8BFB\u53D6\u6765\u6E90\u6267\u884C\u7684\u539F\u8BA2\u5355\u4E0E\u4ED8\u6B3E\u4E8B\u5B9E" }] : [],
14052
+ void 0,
14053
+ {
14054
+ cart_id: cartID,
14055
+ checkout_id: current.checkout_id,
14056
+ checkout_status: current.status,
14057
+ reason: deadlineClosed ? "payment_window_closed" : "checkout_not_payable"
14058
+ }
14059
+ );
14060
+ }
14061
+ __name(checkoutNotPayable, "checkoutNotPayable");
14062
+
14063
+ // src/services/rail/aftercare.ts
14064
+ var target = external_exports.object({ leg_index: external_exports.number().int().nonnegative(), passenger_index: external_exports.number().int().nonnegative() }).strict();
14065
+ var inputSchema = external_exports.object({ operation: external_exports.enum(["refund", "change"]), targets: external_exports.array(target).min(1).max(15), reason: external_exports.string().trim().min(1).max(1e3), scope_revision: external_exports.literal(1), user_confirmed_scope: external_exports.literal(true), change: external_exports.object({ travel_date: external_exports.string().optional(), departure_after: external_exports.string().optional(), arrival_before: external_exports.string().optional(), seat_type: external_exports.string().optional(), train_code: external_exports.string().optional(), constraints: external_exports.string().min(1).max(1e3) }).strict().optional() }).strict();
14066
+ var responseSchema = external_exports.object({ expected_revision: external_exports.number().int().positive(), proposal_revision: external_exports.number().int().positive().optional(), user_approved: external_exports.boolean().optional(), additional_information: external_exports.string().max(1e3).optional(), reason: external_exports.string().max(1e3).optional() }).strict();
14067
+ function railAftercareList(directory, orderID) {
14068
+ return { status: "aftercare_directory", result: { ...directory }, instruction: directory.instruction + "\u6BB5/\u4E58\u5BA2\u7D22\u5F15\u4ECE0\u8D77\uFF0C\u6309\u8FD4\u56DE\u4E8B\u5B9E\u9009\u76EE\u6807\uFF1B\u660E\u786E\u2018\u7B2C\u4E8C\u6BB5\u2019\u7528leg_index:1\u3002\u6574\u7A0B\u6A21\u677F\u5217\u5168\u90E8\u53EF\u7528\u76EE\u6807\uFF0C\u6307\u5B9A\u8303\u56F4\u5219\u4EC5\u4FDD\u7559\u5BF9\u5E94\u76EE\u6807\uFF0C\u4E0D\u624B\u586B\u7968\u4EF7/\u4F9B\u5E94\u5546\u5355\u53F7\u3002\u8303\u56F4\u5DF2\u660E\u786E\u53EA\u8BF4\u660E\u540E\u63D0\u4EA4\uFF1B\u4E0D\u91CD\u65B0\u8BE2\u95EE\u6574\u7A0B\u9009\u62E9\u3002", next: null, recovery: [], interaction: { schema_version: "itpay.interaction.v1", stage: "input_required", input_templates: Object.fromEntries(Object.entries(directory.input_templates).map(([operation, input]) => [operation, fileInputTemplate(`itpay aftercare create --order ${orderID} --input-json <file> --json`, { ...input }, ["targets", "reason", "user_confirmed_scope"])])) } };
14069
+ }
14070
+ __name(railAftercareList, "railAftercareList");
14071
+ function railAftercareEnvelope(view) {
14072
+ const c = view.case;
14073
+ const instruction = c.status === "awaiting_confirmation" ? "\u5C55\u793A\u5F53\u524D\u5177\u4F53\u6539\u7B7E\u65B9\u6848\u3001\u65E7\u65B0\u5BF9\u5E94\u3001\u5DEE\u4EF7\u548C\u6761\u4EF6\uFF1B\u65E7\u8D2D\u4E70\u59D4\u6258\u4E0D\u662F\u65B0\u65B9\u6848/\u8D39\u7528\u6279\u51C6\u3002\u6CA1\u6709\u771F\u5B9E\u56DE\u7B54\u4FDD\u6301false\u5E76\u7B49\u5F85\uFF1B\u672C\u8F6E\u8D39\u7528\u7531\u4EBA\u5DE5\u534F\u8C03\uFF0C\u6CA1\u6709\u81EA\u52A8\u652F\u4ED8\u94FE\u63A5\u3002" : c.status === "needs_input" ? "\u5C55\u793A\u7BA1\u7406\u5458\u8981\u6C42\u8865\u5145\u7684\u5185\u5BB9\uFF0C\u53EA\u8865\u7F3A\u5931\u4E8B\u5B9E\uFF1B\u4FDD\u7559\u539F\u7533\u8BF7\u8303\u56F4\u3002" : c.status === "completed" ? "\u4EBA\u5DE5\u53D7\u7406\u5DF2\u5B8C\u6210\uFF1B\u5206\u522B\u8BF4\u660E\u4F9B\u5E94\u5546\u6838\u9A8C\u7ED3\u679C\u4E0E\u5E73\u53F0\u9000\u6B3E\u91D1\u989D/\u72B6\u6001\u3002\u672A\u9000\u6BB5\u4EC5\u62A5\u544A\u6743\u5A01\u5DF2\u77E5\u4E8B\u5B9E\uFF0C\u4E0D\u4FDD\u8BC1\u4ECD\u53EF\u4E58\uFF1B\u4E0D\u6062\u590D\u5E73\u53F0\u5185\u5BB9\u8BBF\u95EE\u9501\u3002" : c.status === "processing" ? "\u539F\u7533\u8BF7\u6B63\u5728\u4EBA\u5DE5\u529E\u7406\u6216\u8D22\u52A1\u5904\u7406\u4E2D\uFF1B\u6CA1\u6709\u6700\u7EC8\u4E8B\u5B9E\u4E0D\u8BF4\u9000\u7968\u3001\u6539\u7B7E\u6216\u5230\u8D26\u6210\u529F\uFF0C\u4E0D\u91CD\u8BD5\u672A\u77E5\u8D44\u91D1\u3001\u4E0D\u53D6\u6D88\u5DF2\u53D1\u751F\u64CD\u4F5C\u3002" : ["cancelled", "rejected"].includes(c.status) ? "\u8BF4\u660E\u539F\u7533\u8BF7\u5DF2\u53D6\u6D88\u6216\u88AB\u62D2\u7EDD\u53CA\u539F\u56E0\uFF1B\u6CA1\u6709\u64A4\u9500\u5DF2\u53D1\u751F\u4F9B\u5E94\u5546\u64CD\u4F5C\uFF0C\u4E5F\u4E0D\u81EA\u52A8\u521B\u5EFA\u66FF\u4EE3\u8D2D\u4E70\u3002" : "\u5DF2\u63D0\u4EA4\u4EBA\u5DE5\u53D7\u7406\uFF0C\u5C1A\u672A\u786E\u8BA4\u4F9B\u5E94\u5546\u9000\u7968/\u6539\u7B7E\u6216\u94B1\u6B3E\u5230\u8D26\u3002\u5148\u4EA4\u4ED8\u7533\u8BF7\u72B6\u6001\u5165\u53E3\uFF0C\u518D\u6309\u7528\u6237\u610F\u613F\u67E5\u8BE2\u539F\u7533\u8BF7\uFF0C\u4E0D\u5FAA\u73AF\u8F6E\u8BE2\u3002";
14074
+ const cancellation = view.can_cancel ? { cancel_template: fileInputTemplate(`itpay aftercare cancel ${c.case_id} --input-json <file> --json`, { expected_revision: c.revision, reason: "" }, ["reason"]) } : {};
14075
+ const needsReply = ["awaiting_confirmation", "needs_input"].includes(c.status);
14076
+ return { status: c.status, result: { ...view }, instruction, next: needsReply || ["completed", "cancelled", "rejected"].includes(c.status) ? null : { command: `itpay aftercare get ${c.case_id} --json`, reason: "\u6309\u7528\u6237\u8981\u6C42\u8BFB\u53D6\u540C\u4E00\u4EBA\u5DE5\u7533\u8BF7" }, recovery: [], ...needsReply || view.can_cancel ? { interaction: { schema_version: "itpay.interaction.v1", stage: c.status === "awaiting_confirmation" ? "consent_required" : "input_required", ...cancellation, ...needsReply ? { input_template: fileInputTemplate(`itpay aftercare respond ${c.case_id} --input-json <file> --json`, { expected_revision: c.revision, ...c.status === "awaiting_confirmation" ? { proposal_revision: c.proposal_revision, user_approved: false } : { additional_information: "" } }, c.status === "awaiting_confirmation" ? ["user_approved"] : ["additional_information"]) } : {} } } : {} };
14077
+ }
14078
+ __name(railAftercareEnvelope, "railAftercareEnvelope");
14079
+ async function railAftercareCreate(backend, config, orderID, raw) {
14080
+ const parsed = inputSchema.safeParse(raw);
14081
+ if (!parsed.success) throw new CommandContractError("rail_aftercare_input_invalid", "Aftercare input fields or genuine scope confirmation are missing", "Agent\u8BFB\u53D6\u5F53\u524D\u5B8C\u6574\u6A21\u677F\u4FEE\u6B63\u6280\u672F\u5B57\u6BB5\uFF1B\u53EA\u95EE\u7F3A\u5931\u7684\u771F\u5B9E\u8303\u56F4/\u6539\u7B7E\u610F\u5411\uFF0C\u4E0D\u8BA9\u7528\u6237\u586B\u6280\u672FJSON\u3002", [{ command: `itpay aftercare list --order ${orderID} --json`, reason: "\u8BFB\u53D6\u5F53\u524D\u884C\u7A0B\u3001\u76EE\u6807\u548C\u5B8C\u6574\u6A21\u677F" }]);
14082
+ const value = parsed.data;
14083
+ const change = value.change;
14084
+ const input = { operation: value.operation, targets: value.targets, reason: value.reason, scope_revision: value.scope_revision, user_confirmed_scope: value.user_confirmed_scope, ...change ? { change: { constraints: change.constraints, ...change.travel_date !== void 0 ? { travel_date: change.travel_date } : {}, ...change.departure_after !== void 0 ? { departure_after: change.departure_after } : {}, ...change.arrival_before !== void 0 ? { arrival_before: change.arrival_before } : {}, ...change.seat_type !== void 0 ? { seat_type: change.seat_type } : {}, ...change.train_code !== void 0 ? { train_code: change.train_code } : {} } } : {} };
14085
+ return railAftercareEnvelope(await backend.createRailAftercare(orderID, input, await operationID(config, `aftercare.create:${orderID}:${JSON.stringify(input)}`)));
14086
+ }
14087
+ __name(railAftercareCreate, "railAftercareCreate");
13949
14088
  async function railAftercareRespond(backend, id, raw, cancel = false) {
13950
14089
  const parsed = responseSchema.safeParse(raw);
13951
14090
  if (!parsed.success) throw new CommandContractError("rail_aftercare_input_invalid", "Current revision or response fields are missing", "\u4F7F\u7528\u539F\u7533\u8BF7\u5F53\u524D\u8FD4\u56DE\u6A21\u677F\uFF1B\u5B9E\u8D28\u65B9\u6848\u53D8\u5316\u987B\u91CD\u65B0\u53D6\u5F97\u660E\u786E\u540C\u610F\u3002", [{ command: `itpay aftercare get ${id} --json`, reason: "\u8BFB\u53D6\u540C\u4E00\u7533\u8BF7\u5F53\u524D\u65B9\u6848\u548C\u7248\u672C" }]);
@@ -13962,23 +14101,30 @@ async function railAftercareOrder(backend, order, envelope) {
13962
14101
  __name(railAftercareOrder, "railAftercareOrder");
13963
14102
 
13964
14103
  // src/state/task_journal.ts
13965
- import { existsSync as existsSync3, mkdirSync as mkdirSync5, readFileSync as readFileSync5, renameSync as renameSync2, writeFileSync as writeFileSync4 } from "node:fs";
13966
- import { dirname as dirname3 } from "node:path";
13967
- var PAUSED_STAGES = /* @__PURE__ */ new Set([
13968
- "login_required",
13969
- "rate_limited",
13970
- "quota_paused",
13971
- "auth_pending",
13972
- "awaiting_input"
13973
- ]);
13974
- var TERMINAL_STAGES = /* @__PURE__ */ new Set([
13975
- "completed",
13976
- "delivered",
13977
- "issued",
13978
- "failed",
13979
- "cancelled",
13980
- "refunded"
13981
- ]);
14104
+ import { randomUUID as randomUUID5, createHash as createHash6 } from "node:crypto";
14105
+ import { existsSync as existsSync3, linkSync as linkSync4, lstatSync as lstatSync4, mkdirSync as mkdirSync5, readFileSync as readFileSync5, readdirSync as readdirSync3, unlinkSync as unlinkSync4, writeFileSync as writeFileSync4 } from "node:fs";
14106
+ import { join as join2 } from "node:path";
14107
+ var PAUSED_STAGES = /* @__PURE__ */ new Set(["login_required", "rate_limited", "quota_paused", "auth_pending", "awaiting_input"]);
14108
+ var TERMINAL_STAGES = /* @__PURE__ */ new Set(["completed", "delivered", "issued", "failed", "cancelled", "refunded"]);
14109
+ var object2 = /* @__PURE__ */ __name((v) => v !== null && typeof v === "object" && !Array.isArray(v), "object");
14110
+ var finite = /* @__PURE__ */ __name((v) => typeof v === "number" && Number.isFinite(v) && v >= 0, "finite");
14111
+ function validTask(v) {
14112
+ return object2(v) && typeof v.service_execution_id === "string" && typeof v.stage === "string" && typeof v.updated_at === "string" && Number.isFinite(Date.parse(v.updated_at)) && (v.service_id === void 0 || typeof v.service_id === "string") && (v.resume_command === void 0 || typeof v.resume_command === "string") && (v.automatic_wait_ms === void 0 || finite(v.automatic_wait_ms));
14113
+ }
14114
+ __name(validTask, "validTask");
14115
+ function validChange(v) {
14116
+ if (!object2(v) || v.schema_version !== "itpay.task_change.v1" || typeof v.event_id !== "string" || typeof v.id !== "string" || typeof v.updated_at !== "string" || !Number.isFinite(Date.parse(v.updated_at)) || typeof v.monotonic !== "string" || !/^\d{1,30}$/.test(v.monotonic)) return false;
14117
+ if (v.kind === "clear") return true;
14118
+ if (v.kind === "wait") return finite(v.milliseconds);
14119
+ if (v.kind === "observe") return typeof v.stage === "string" && (v.resume_command === void 0 || typeof v.resume_command === "string");
14120
+ return v.kind === "record" && object2(v.task) && validTask({ ...v.task, updated_at: v.updated_at }) && v.task.service_execution_id === v.id;
14121
+ }
14122
+ __name(validChange, "validChange");
14123
+ var taskHash = /* @__PURE__ */ __name((id) => createHash6("sha256").update(id).digest("hex"), "taskHash");
14124
+ function invalid3() {
14125
+ throw Object.assign(new Error("ItPay task journal is invalid; original records are unchanged"), { code: "task_journal_invalid" });
14126
+ }
14127
+ __name(invalid3, "invalid");
13982
14128
  var TaskJournal = class {
13983
14129
  constructor(path3) {
13984
14130
  this.path = path3;
@@ -13988,83 +14134,103 @@ var TaskJournal = class {
13988
14134
  __name(this, "TaskJournal");
13989
14135
  }
13990
14136
  record(task) {
13991
- const file = this.readFile();
13992
- file.tasks[task.service_execution_id] = {
13993
- ...task,
13994
- ...file.tasks[task.service_execution_id]?.automatic_wait_ms !== void 0 && task.automatic_wait_ms === void 0 ? { automatic_wait_ms: file.tasks[task.service_execution_id].automatic_wait_ms } : {},
13995
- updated_at: (/* @__PURE__ */ new Date()).toISOString()
13996
- };
13997
- this.writeFile(file);
13998
- }
13999
- clear(serviceExecutionID) {
14000
- const file = this.readFile();
14001
- if (!file.tasks[serviceExecutionID]) return;
14002
- delete file.tasks[serviceExecutionID];
14003
- this.writeFile(file);
14004
- }
14005
- // Observe the latest stage without deleting history; terminal stages stop
14006
- // the task from counting as resumable.
14007
- observe(serviceExecutionID, stage, resumeCommand) {
14008
- const file = this.readFile();
14009
- const existing = file.tasks[serviceExecutionID];
14010
- if (existing && existing.stage === stage && (resumeCommand === void 0 || existing.resume_command === resumeCommand)) return;
14011
- file.tasks[serviceExecutionID] = {
14012
- service_execution_id: serviceExecutionID,
14013
- ...existing?.service_id ? { service_id: existing.service_id } : {},
14014
- stage,
14015
- ...existing?.automatic_wait_ms !== void 0 ? { automatic_wait_ms: existing.automatic_wait_ms } : {},
14016
- ...resumeCommand ?? existing?.resume_command ? { resume_command: resumeCommand ?? existing.resume_command } : {},
14017
- updated_at: (/* @__PURE__ */ new Date()).toISOString()
14018
- };
14019
- this.writeFile(file);
14137
+ this.readFile(task.service_execution_id);
14138
+ this.append({ kind: "record", id: task.service_execution_id, task });
14020
14139
  }
14021
- remainingAutomaticWait(serviceExecutionID) {
14022
- if (existsSync3(this.path)) {
14023
- try {
14024
- const raw = JSON.parse(readFileSync5(this.path, "utf8"));
14025
- if (raw.schema_version !== "itpay.task_journal.v1" || !raw.tasks || typeof raw.tasks !== "object") return 0;
14026
- } catch {
14027
- return 0;
14028
- }
14140
+ clear(id) {
14141
+ if (this.readFile(id).tasks[id]) this.append({ kind: "clear", id });
14142
+ }
14143
+ observe(id, stage, resumeCommand) {
14144
+ const existing = this.readFile(id).tasks[id];
14145
+ if (existing && (TERMINAL_STAGES.has(existing.stage) || existing.stage === stage && (resumeCommand === void 0 || existing.resume_command === resumeCommand))) return;
14146
+ this.append({ kind: "observe", id, stage, ...resumeCommand === void 0 ? {} : { resume_command: resumeCommand } });
14147
+ }
14148
+ remainingAutomaticWait(id) {
14149
+ try {
14150
+ return Math.max(0, 12e4 - (this.readFile(id).spent.get(id) ?? 0));
14151
+ } catch {
14152
+ return 0;
14029
14153
  }
14030
- const spent = this.readFile().tasks[serviceExecutionID]?.automatic_wait_ms ?? 0;
14031
- return typeof spent === "number" && Number.isFinite(spent) && spent >= 0 ? Math.max(0, 12e4 - spent) : 0;
14032
14154
  }
14033
- recordAutomaticWait(serviceExecutionID, milliseconds) {
14034
- if (this.remainingAutomaticWait(serviceExecutionID) === 0) return 0;
14035
- const file = this.readFile();
14036
- const existing = file.tasks[serviceExecutionID];
14037
- const spent = Math.min(12e4, (existing?.automatic_wait_ms ?? 0) + Math.max(0, milliseconds));
14038
- file.tasks[serviceExecutionID] = { ...existing ?? { service_execution_id: serviceExecutionID, stage: "running" }, automatic_wait_ms: spent, updated_at: (/* @__PURE__ */ new Date()).toISOString() };
14039
- this.writeFile(file);
14040
- return 12e4 - spent;
14155
+ recordAutomaticWait(id, milliseconds) {
14156
+ if (!finite(milliseconds) || this.remainingAutomaticWait(id) === 0) return 0;
14157
+ if (milliseconds > 0) this.append({ kind: "wait", id, milliseconds: Math.min(12e4, milliseconds) });
14158
+ return this.remainingAutomaticWait(id);
14041
14159
  }
14042
- // Tasks paused behind login/quota gates, newest first. Terminal or
14043
- // completed tasks never count as "still waiting for login".
14044
14160
  pausedTasks() {
14045
- const file = this.readFile();
14046
- return Object.values(file.tasks).filter((task) => PAUSED_STAGES.has(task.stage) && !TERMINAL_STAGES.has(task.stage)).sort((left, right) => right.updated_at.localeCompare(left.updated_at));
14161
+ return Object.values(this.readFile().tasks).filter((t) => PAUSED_STAGES.has(t.stage) && !TERMINAL_STAGES.has(t.stage)).sort((a, b) => b.updated_at.localeCompare(a.updated_at));
14047
14162
  }
14048
- readFile() {
14049
- if (!existsSync3(this.path)) return { schema_version: "itpay.task_journal.v1", tasks: {} };
14163
+ readFile(onlyID) {
14164
+ const tasks = /* @__PURE__ */ new Map(), spent = /* @__PURE__ */ new Map(), cleared = /* @__PURE__ */ new Set();
14165
+ if (existsSync3(this.path)) {
14166
+ let old;
14167
+ try {
14168
+ old = JSON.parse(readFileSync5(this.path, "utf8"));
14169
+ } catch {
14170
+ return invalid3();
14171
+ }
14172
+ if (!object2(old) || old.schema_version !== "itpay.task_journal.v1" || !object2(old.tasks)) return invalid3();
14173
+ for (const [id, task] of Object.entries(old.tasks)) {
14174
+ if (!validTask(task) || task.service_execution_id !== id) return invalid3();
14175
+ if (onlyID === void 0 || onlyID === id) {
14176
+ tasks.set(id, task);
14177
+ spent.set(id, task.automatic_wait_ms ?? 0);
14178
+ }
14179
+ }
14180
+ }
14181
+ const directory = this.path + ".d";
14182
+ const changes = [];
14183
+ if (existsSync3(directory) && (!lstatSync4(directory).isDirectory() || lstatSync4(directory).isSymbolicLink())) return invalid3();
14184
+ if (existsSync3(directory)) for (const name of readdirSync3(directory).filter((n) => n.endsWith(".json") && (onlyID === void 0 || n.startsWith(taskHash(onlyID) + "-") || !/^\w{64}-[\da-f-]+\.json$/.test(n)))) {
14185
+ const path3 = join2(directory, name);
14186
+ const stat = lstatSync4(path3);
14187
+ if (!stat.isFile() || stat.isSymbolicLink()) return invalid3();
14188
+ let raw;
14189
+ try {
14190
+ raw = JSON.parse(readFileSync5(path3, "utf8"));
14191
+ } catch {
14192
+ return invalid3();
14193
+ }
14194
+ if (!validChange(raw) || name !== taskHash(raw.id) + "-" + raw.event_id + ".json") return invalid3();
14195
+ changes.push(raw);
14196
+ }
14197
+ changes.sort((a, b) => a.updated_at.localeCompare(b.updated_at) || (BigInt(a.monotonic) < BigInt(b.monotonic) ? -1 : BigInt(a.monotonic) > BigInt(b.monotonic) ? 1 : a.event_id.localeCompare(b.event_id)));
14198
+ for (const change of changes) {
14199
+ const id = change.id, existing = tasks.get(id);
14200
+ if (change.kind === "wait") {
14201
+ spent.set(id, Math.min(12e4, (spent.get(id) ?? 0) + change.milliseconds));
14202
+ if (!cleared.has(id)) tasks.set(id, { ...existing ?? { service_execution_id: id, stage: "running" }, updated_at: change.updated_at, automatic_wait_ms: spent.get(id) ?? 0 });
14203
+ } else if (change.kind === "clear") {
14204
+ tasks.delete(id);
14205
+ cleared.add(id);
14206
+ } else if (change.kind === "record") {
14207
+ cleared.delete(id);
14208
+ spent.set(id, Math.max(spent.get(id) ?? 0, change.task.automatic_wait_ms ?? 0));
14209
+ tasks.set(id, { ...change.task, updated_at: change.updated_at, automatic_wait_ms: spent.get(id) ?? 0 });
14210
+ } else if (!cleared.has(id) && (!existing || !TERMINAL_STAGES.has(existing.stage))) {
14211
+ tasks.set(id, { ...existing ?? { service_execution_id: id }, stage: change.stage, ...change.resume_command === void 0 ? {} : { resume_command: change.resume_command }, updated_at: change.updated_at, automatic_wait_ms: spent.get(id) ?? 0 });
14212
+ }
14213
+ }
14214
+ return { tasks: Object.fromEntries([...tasks].sort((a, b) => b[1].updated_at.localeCompare(a[1].updated_at)).slice(0, 50)), spent };
14215
+ }
14216
+ append(change) {
14217
+ const event = { ...change, schema_version: "itpay.task_change.v1", event_id: randomUUID5(), updated_at: (/* @__PURE__ */ new Date()).toISOString(), monotonic: process.hrtime.bigint().toString() };
14218
+ if (!validChange(event)) return invalid3();
14219
+ const directory = this.path + ".d";
14220
+ mkdirSync5(directory, { recursive: true, mode: 448 });
14221
+ if (!lstatSync4(directory).isDirectory() || lstatSync4(directory).isSymbolicLink()) return invalid3();
14222
+ const temp = join2(directory, "." + event.event_id + ".tmp"), target2 = join2(directory, taskHash(event.id) + "-" + event.event_id + ".json");
14050
14223
  try {
14051
- const parsed = JSON.parse(readFileSync5(this.path, "utf8"));
14052
- if (parsed.schema_version !== "itpay.task_journal.v1" || !parsed.tasks || typeof parsed.tasks !== "object") {
14053
- return { schema_version: "itpay.task_journal.v1", tasks: {} };
14224
+ writeFileSync4(temp, JSON.stringify(event), { flag: "wx", mode: 384 });
14225
+ linkSync4(temp, target2);
14226
+ } finally {
14227
+ try {
14228
+ unlinkSync4(temp);
14229
+ } catch (e) {
14230
+ if (!object2(e) || e.code !== "ENOENT") throw e;
14054
14231
  }
14055
- return parsed;
14056
- } catch {
14057
- return { schema_version: "itpay.task_journal.v1", tasks: {} };
14058
14232
  }
14059
14233
  }
14060
- writeFile(file) {
14061
- const entries = Object.entries(file.tasks).sort((left, right) => right[1].updated_at.localeCompare(left[1].updated_at));
14062
- file.tasks = Object.fromEntries(entries.slice(0, 50));
14063
- mkdirSync5(dirname3(this.path), { recursive: true, mode: 448 });
14064
- const tmp = `${this.path}.${process.pid}.tmp`;
14065
- writeFileSync4(tmp, JSON.stringify(file), { mode: 384 });
14066
- renameSync2(tmp, this.path);
14067
- }
14068
14234
  };
14069
14235
 
14070
14236
  // src/render/markdown.ts
@@ -14483,10 +14649,10 @@ function tokenizedCheckoutURL(checkoutURL, displayToken, qrPayload) {
14483
14649
  __name(tokenizedCheckoutURL, "tokenizedCheckoutURL");
14484
14650
  function publicPurchaseTemplate(value) {
14485
14651
  if (value === void 0) return void 0;
14486
- const invalid4 = /* @__PURE__ */ __name(() => new CommandContractError("public_operation_contract_invalid", "incomplete public purchase operation", "\u670D\u52A1\u8FD4\u56DE\u7684\u51C6\u5907\u8D2D\u4E70\u5408\u540C\u4E0D\u5B8C\u6574\uFF1B\u4FDD\u7559\u5F53\u524D\u5FEB\u7167\u4E0E\u5DF2\u6709\u8D2D\u4E70\u5E76\u505C\u6B62\uFF0C\u4E0D\u80FD\u9000\u56DE\u65E7\u5165\u53E3\u62FC\u63A5\u51ED\u636E\u3002", [], void 0, { reason: "purchase_contract_missing" }), "invalid");
14487
- if (typeof value !== "object" || value === null || Array.isArray(value) || !("service_id" in value) || typeof value.service_id !== "string" || !("operation_id" in value) || typeof value.operation_id !== "string" || !("input" in value) || typeof value.input !== "object" || value.input === null || Array.isArray(value.input) || !("continuation" in value)) throw invalid4();
14652
+ const invalid5 = /* @__PURE__ */ __name(() => new CommandContractError("public_operation_contract_invalid", "incomplete public purchase operation", "\u670D\u52A1\u8FD4\u56DE\u7684\u51C6\u5907\u8D2D\u4E70\u5408\u540C\u4E0D\u5B8C\u6574\uFF1B\u4FDD\u7559\u5F53\u524D\u5FEB\u7167\u4E0E\u5DF2\u6709\u8D2D\u4E70\u5E76\u505C\u6B62\uFF0C\u4E0D\u80FD\u9000\u56DE\u65E7\u5165\u53E3\u62FC\u63A5\u51ED\u636E\u3002", [], void 0, { reason: "purchase_contract_missing" }), "invalid");
14653
+ if (typeof value !== "object" || value === null || Array.isArray(value) || !("service_id" in value) || typeof value.service_id !== "string" || !("operation_id" in value) || typeof value.operation_id !== "string" || !("input" in value) || typeof value.input !== "object" || value.input === null || Array.isArray(value.input) || !("continuation" in value)) throw invalid5();
14488
14654
  const ref = value.continuation;
14489
- if (typeof ref !== "object" || ref === null || Array.isArray(ref) || !("service_execution_id" in ref) || typeof ref.service_execution_id !== "string" || !("snapshot_id" in ref) || typeof ref.snapshot_id !== "string") throw invalid4();
14655
+ if (typeof ref !== "object" || ref === null || Array.isArray(ref) || !("service_execution_id" in ref) || typeof ref.service_execution_id !== "string" || !("snapshot_id" in ref) || typeof ref.snapshot_id !== "string") throw invalid5();
14490
14656
  const template = fileInputTemplate(`itpay services run ${shellArgument(value.service_id)} --operation ${shellArgument(value.operation_id)} --input-json <file> --json`, { input: value.input, continuation: { service_execution_id: ref.service_execution_id, snapshot_id: ref.snapshot_id } });
14491
14657
  return { ...template, input_example: template.file_content };
14492
14658
  }
@@ -14559,6 +14725,8 @@ var RAIL_SERVICE_GUIDANCE = {
14559
14725
  { name: "origin_location", description: "\u5DF2\u77E5\u5750\u6807\u5BF9\u8C61\uFF08\u9AD8\u5FB7 GCJ-02\uFF09" },
14560
14726
  { name: "destination_location", description: "\u76EE\u7684\u5730\u5750\u6807\u5BF9\u8C61" },
14561
14727
  { name: "depart_after", description: "\u4E0D\u65E9\u4E8E\u8BE5\u65F6\u95F4\u51FA\u53D1" },
14728
+ { name: "depart_before", description: "\u4E0D\u665A\u4E8E\u8BE5\u65F6\u95F4\u51FA\u53D1\uFF1B\u4FDD\u7559\u7528\u6237\u660E\u786E\u4E0A\u9650" },
14729
+ { name: "arrive_after", description: "\u4E0D\u65E9\u4E8E\u8BE5\u65F6\u95F4\u5230\u8FBE\uFF1B\u4E0E\u6700\u665A\u5230\u8FBE\u4E00\u8D77\u4F5C\u4E3A\u8D44\u683C\u6761\u4EF6\uFF0C\u4E0D\u53EA\u4F5C\u6392\u5E8F" },
14562
14730
  { name: "depart_before", description: "\u4E0D\u665A\u4E8E\u8BE5\u65F6\u95F4\u51FA\u53D1" },
14563
14731
  { name: "arrive_before", description: "\u4E0D\u665A\u4E8E\u8BE5\u65F6\u95F4\u5230\u8FBE" },
14564
14732
  { name: "user_query", description: "\u65C5\u884C\u9700\u6C42\u539F\u8BDD\uFF0C\u6700\u591A4096 UTF-8\u5B57\u8282\uFF1B\u65F6\u95F4\u7B49\u660E\u786E\u6761\u4EF6\u4ECD\u586B\u5199\u5BF9\u5E94\u7ED3\u6784\u5316\u5B57\u6BB5" },
@@ -15745,11 +15913,11 @@ function writeSavedPage(envelope, options, key, offset, continuation, updateMeta
15745
15913
  const render = /* @__PURE__ */ __name((output) => writeCommandEnvelope(envelope, { ...options, output }), "render");
15746
15914
  if (!options.all) {
15747
15915
  for (; ; ) {
15748
- let text = "";
15916
+ let text2 = "";
15749
15917
  render((value) => {
15750
- text += value;
15918
+ text2 += value;
15751
15919
  });
15752
- if (Buffer.byteLength(text, "utf8") <= bound) break;
15920
+ if (Buffer.byteLength(text2, "utf8") <= bound) break;
15753
15921
  if (rows.length <= 1) {
15754
15922
  throw new CommandContractError(
15755
15923
  "saved_row_too_large",
@@ -16407,7 +16575,7 @@ function serviceAdapterKey(execution) {
16407
16575
  const binding = execution.public_binding;
16408
16576
  if (binding) {
16409
16577
  if (binding.adapter_key === "schema.v1") return "schema.v1";
16410
- if (binding.adapter_key === "rail.v1" && ["scv_itpay_rail_public_v1", "scv_itpay_rail_public_v1_capacity_20261015"].includes(binding.service_definition_version)) return "rail.v1";
16578
+ if (binding.adapter_key === "rail.v1" && ["scv_itpay_rail_public_v1", "scv_itpay_rail_public_v1_capacity_20261015", "scv_itpay_rail_public_v5"].includes(binding.service_definition_version)) return "rail.v1";
16411
16579
  return "unsupported";
16412
16580
  }
16413
16581
  const versions = legacyRailContracts.get(execution.service_id);
@@ -16440,12 +16608,69 @@ function projectCheckoutPresentation(presentation, model) {
16440
16608
  }
16441
16609
  __name(projectCheckoutPresentation, "projectCheckoutPresentation");
16442
16610
 
16611
+ // src/render/browser.ts
16612
+ import { spawn } from "node:child_process";
16613
+ import { platform } from "node:os";
16614
+ function isPresentableURL(raw, baseURL, env = process.env) {
16615
+ let url;
16616
+ try {
16617
+ url = new URL(raw);
16618
+ } catch {
16619
+ return false;
16620
+ }
16621
+ if (url.username || url.password) return false;
16622
+ if (env.ITPAY_CLI_DEV === "1" && /^http:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/.test(url.origin)) return true;
16623
+ if (url.protocol !== "https:") return false;
16624
+ const allowedOrigins = new Set(OFFICIAL_BACKEND_URLS);
16625
+ if (baseURL) {
16626
+ try {
16627
+ allowedOrigins.add(new URL(baseURL).origin);
16628
+ } catch {
16629
+ }
16630
+ }
16631
+ return allowedOrigins.has(url.origin);
16632
+ }
16633
+ __name(isPresentableURL, "isPresentableURL");
16634
+ function openInSystemBrowser(raw, baseURL, env = process.env) {
16635
+ if (!isPresentableURL(raw, baseURL, env)) {
16636
+ return Promise.resolve({ status: "failed", reason: "url_rejected" });
16637
+ }
16638
+ const [command, args] = openerArgv(raw);
16639
+ if (!command) {
16640
+ return Promise.resolve({ status: "unavailable", reason: "no system opener on this platform" });
16641
+ }
16642
+ return new Promise((resolvePromise) => {
16643
+ const child = spawn(command, args, { detached: true, stdio: "ignore" });
16644
+ child.once("error", (error) => resolvePromise({ status: "failed", reason: error.message }));
16645
+ child.once("spawn", () => {
16646
+ child.unref();
16647
+ resolvePromise({ status: "dispatch_accepted", argv: [command, ...args] });
16648
+ });
16649
+ });
16650
+ }
16651
+ __name(openInSystemBrowser, "openInSystemBrowser");
16652
+ function openerArgv(url) {
16653
+ switch (platform()) {
16654
+ case "darwin":
16655
+ return ["open", [url]];
16656
+ case "win32":
16657
+ return ["cmd.exe", ["/c", "start", "", url]];
16658
+ case "linux":
16659
+ case "freebsd":
16660
+ case "openbsd":
16661
+ return ["xdg-open", [url]];
16662
+ default:
16663
+ return [void 0, []];
16664
+ }
16665
+ }
16666
+ __name(openerArgv, "openerArgv");
16667
+
16443
16668
  // src/render/qr.ts
16444
16669
  var import_qrcode = __toESM(require_lib(), 1);
16445
16670
  import fs from "node:fs/promises";
16446
16671
  import os from "node:os";
16447
16672
  import path from "node:path";
16448
- import { randomUUID as randomUUID5 } from "node:crypto";
16673
+ import { randomUUID as randomUUID6 } from "node:crypto";
16449
16674
  function terminalQRType(format) {
16450
16675
  return format === "utf8" ? "utf8" : "terminal";
16451
16676
  }
@@ -16460,7 +16685,7 @@ async function renderTerminalQR(url, format) {
16460
16685
  __name(renderTerminalQR, "renderTerminalQR");
16461
16686
  async function writeLocalPNG(url) {
16462
16687
  const dir = await fs.mkdtemp(path.join(process.env.ITPAY_STATE_DIR || os.tmpdir(), "itpay-v3-"));
16463
- const filePath = path.join(dir, `itpay-${randomUUID5()}.png`);
16688
+ const filePath = path.join(dir, `itpay-${randomUUID6()}.png`);
16464
16689
  await import_qrcode.default.toFile(filePath, url, {
16465
16690
  type: "png",
16466
16691
  errorCorrectionLevel: "M",
@@ -16494,15 +16719,15 @@ function renderInlineTerminalImage(filePath, out) {
16494
16719
  __name(renderInlineTerminalImage, "renderInlineTerminalImage");
16495
16720
 
16496
16721
  // src/render/ide.ts
16497
- import { mkdirSync as mkdirSync6, readFileSync as readFileSync7, renameSync as renameSync3, writeFileSync as writeFileSync5 } from "node:fs";
16498
- import { join as join2 } from "node:path";
16722
+ import { mkdirSync as mkdirSync6, readFileSync as readFileSync7, renameSync as renameSync2, writeFileSync as writeFileSync5 } from "node:fs";
16723
+ import { join as join3 } from "node:path";
16499
16724
  import { tmpdir } from "node:os";
16500
- import { createHash as createHash6, randomUUID as randomUUID6 } from "node:crypto";
16725
+ import { createHash as createHash7, randomUUID as randomUUID7 } from "node:crypto";
16501
16726
  var IDE_ATTACH_REASON = "\u7ACB\u5373\u5C55\u793A\u5DF2\u6838\u9A8C\u5B98\u65B9\u94FE\u63A5\u548C\u771F\u5B9E\u671F\u9650\uFF1B\u56FE\u7247\u53EA\u662F\u589E\u5F3A\u5448\u73B0\u3002\u5DF2\u6709\u5DE5\u5177\u652F\u6301\u65F6\u5C55\u793A\u56FE\u7247\uFF0C\u5931\u8D25\u6216\u4E0D\u53EF\u7528\u5219\u5F53\u8F6E\u4EA4\u4ED8\u540C\u4E00\u94FE\u63A5\uFF0C\u4E0D\u7814\u7A76\u5DE5\u5177\u3001\u4E0D\u7B49\u5F85\u56FE\u7247\u786E\u8BA4\u3001\u4E0D\u91CD\u5EFA\u9875\u9762\u6216\u5BA3\u79F0\u4ED8\u6B3E\u3002";
16502
16727
  function canonicalDir(env = process.env) {
16503
16728
  const override = env.ITPAY_IDE_IMAGE_DIR_OVERRIDE;
16504
16729
  if (override && override.length > 0) return override;
16505
- return join2(tmpdir(), "itpay-v3-qr");
16730
+ return join3(tmpdir(), "itpay-v3-qr");
16506
16731
  }
16507
16732
  __name(canonicalDir, "canonicalDir");
16508
16733
  function resolveIdeImageDirs(env = process.env) {
@@ -16520,8 +16745,8 @@ function resolveIdeImageDirs(env = process.env) {
16520
16745
  }
16521
16746
  __name(resolveIdeImageDirs, "resolveIdeImageDirs");
16522
16747
  function stableNameFor(kind, id) {
16523
- const safeID = id.replace(/[^a-zA-Z0-9_-]/g, "_") || randomUUID6();
16524
- const hash = createHash6("sha1").update(`${kind}:${id}`).digest("hex").slice(0, 6);
16748
+ const safeID = id.replace(/[^a-zA-Z0-9_-]/g, "_") || randomUUID7();
16749
+ const hash = createHash7("sha1").update(`${kind}:${id}`).digest("hex").slice(0, 6);
16525
16750
  return `itpay-v3-${kind}-${safeID}-${hash}`;
16526
16751
  }
16527
16752
  __name(stableNameFor, "stableNameFor");
@@ -16554,9 +16779,9 @@ async function detectImageFormat(url, fetchFn) {
16554
16779
  }
16555
16780
  __name(detectImageFormat, "detectImageFormat");
16556
16781
  function atomicWrite(filePath, body) {
16557
- const tmp = `${filePath}.tmp-${randomUUID6()}`;
16782
+ const tmp = `${filePath}.tmp-${randomUUID7()}`;
16558
16783
  writeFileSync5(tmp, body);
16559
- renameSync3(tmp, filePath);
16784
+ renameSync2(tmp, filePath);
16560
16785
  }
16561
16786
  __name(atomicWrite, "atomicWrite");
16562
16787
  function mirrorToDirs(fileName, body, dirs) {
@@ -16564,7 +16789,7 @@ function mirrorToDirs(fileName, body, dirs) {
16564
16789
  for (const dir of dirs.slice(1)) {
16565
16790
  try {
16566
16791
  mkdirSync6(dir, { recursive: true });
16567
- const target2 = join2(dir, fileName);
16792
+ const target2 = join3(dir, fileName);
16568
16793
  atomicWrite(target2, body);
16569
16794
  written.push(target2);
16570
16795
  } catch {
@@ -16608,7 +16833,7 @@ async function downloadBrandQRToTmp(url, kind, id, options = {}) {
16608
16833
  if (!url) {
16609
16834
  return { ok: false, reason: "no qr_png_url on plan" };
16610
16835
  }
16611
- const stem = stableNameFor(kind, id ?? randomUUID6());
16836
+ const stem = stableNameFor(kind, id ?? randomUUID7());
16612
16837
  const dirs = resolveIdeImageDirs();
16613
16838
  const canonical = dirs[0];
16614
16839
  if (!canonical) {
@@ -16636,7 +16861,7 @@ async function downloadBrandQRToTmp(url, kind, id, options = {}) {
16636
16861
  if (timer) clearTimeout(timer);
16637
16862
  }
16638
16863
  const fileName = `${stem}${detected.ext}`;
16639
- const filePath = join2(canonical, fileName);
16864
+ const filePath = join3(canonical, fileName);
16640
16865
  atomicWrite(filePath, detected.body);
16641
16866
  const mirrors = mirrorToDirs(fileName, detected.body, dirs);
16642
16867
  return {
@@ -17306,6 +17531,23 @@ async function presentServiceCheckout(backend, config, serviceExecutionID, respo
17306
17531
  assertCheckoutPayable(checkout, authoritative, response.cart.cart_id, serviceExecutionID);
17307
17532
  if (authoritative) response.cart.items = authoritative.items;
17308
17533
  const checkoutID = checkout.checkout.checkout_id;
17534
+ const agentType = options.agentType ?? config.agentType;
17535
+ if (agentType === "dot" || agentType === "muse") {
17536
+ const entry = checkout.official_entry;
17537
+ let url;
17538
+ try {
17539
+ if (entry) url = new URL(entry.url);
17540
+ } catch {
17541
+ }
17542
+ const readOriginal = { command: `itpay --agent-type ${agentType} services get ${serviceExecutionID} --json`, reason: "\u7528\u6237\u5B8C\u6210\u9875\u9762\u64CD\u4F5C\u540E\u8BFB\u53D6\u539F\u4EFB\u52A1\u4E8B\u5B9E" };
17543
+ if (!entry || entry.access !== "account_session" || entry.url !== checkout.checkout_url || !url || !isPresentableURL(entry.url, config.baseURL) || url.protocol !== "https:" || url.username || url.password || url.search || url.hash || url.pathname !== `/checkout/${encodeURIComponent(checkoutID)}`) {
17544
+ throw new CommandContractError("secure_handoff_unavailable", "original purchase has no verified account-session entry", "\u4FDD\u7559\u539F\u8D2D\u4E70\uFF1B\u5F53\u524D\u8D26\u53F7\u5B89\u5168\u5165\u53E3\u4E0D\u53EF\u7528\uFF0C\u4E0D\u5C55\u793A\u6216\u62FC\u63A5 bearer \u94FE\u63A5\uFF0C\u4E0D\u6362\u8EAB\u4EFD\u6216\u91CD\u5EFA\u8D2D\u4E70\u3002", [readOriginal], void 0, { service_execution_id: serviceExecutionID, checkout_id: checkoutID });
17545
+ }
17546
+ const { itinerary: itinerary2 } = authoritative ? projectCheckoutPresentation(authoritative, currentModel) : {};
17547
+ const effects = { page_created: !response.handoff_reissued, page_reused: response.handoff_reissued === true, payment_requested: false, charged: false, human_page_action_required: true };
17548
+ writeCommandEnvelope({ status: "human_checkout_required", result: { service_execution_id: serviceExecutionID, checkout_id: checkoutID, amount: formatMoney(checkout.checkout.amount_minor, checkout.checkout.currency), effects, ...itinerary2 ? { itinerary: itinerary2 } : {}, agent_facts: presentAgent({ service_execution_id: serviceExecutionID, checkout_id: checkoutID, status: "human_checkout_required", checkout: { official_entry: entry }, effects }, { allowedOrigins: OFFICIAL_BACKEND_URLS }) }, handoff: { url: entry.url, purpose: entry.purpose, access: entry.access, ...entry.expires_at ? { expires_at: entry.expires_at } : {} }, instruction: "\u7ACB\u5373\u5C55\u793A\u5B98\u65B9\u94FE\u63A5\u53CA\u91D1\u989D\uFF1B\u7528\u6237\u767B\u5F55\u53D1\u8D77\u8FDE\u63A5\u7684\u8D26\u53F7\u5B8C\u6210\u5F53\u524D\u6B65\u9AA4\u3002\u4E8C\u7EF4\u7801\u4E0D\u662F\u524D\u7F6E\u6761\u4EF6\uFF0C\u6253\u5F00\u94FE\u63A5\u4E0D\u4EE3\u8868\u4ED8\u6B3E\u6216\u51FA\u7968\u3002\u7528\u6237\u8868\u793A\u5B8C\u6210\u540E\u8BFB\u53D6\u539F\u4EFB\u52A1\u4E8B\u5B9E\uFF0C\u4E0D\u91CD\u590D\u786E\u8BA4\u3001\u6362\u5355\u6216\u81EA\u52A8\u4ED8\u6B3E\u3002", next: readOriginal, recovery: [] }, { ...options.jsonOutput !== void 0 ? { jsonOutput: options.jsonOutput } : {}, ...options.output ? { output: options.output } : {} });
17549
+ return;
17550
+ }
17309
17551
  const displayToken = checkout.display_token;
17310
17552
  const locale = normalizeCardLocale(options.locale);
17311
17553
  const checkoutURL = tokenizedCheckoutURL(checkout.checkout_url, displayToken, checkout.qr_payload);
@@ -17449,29 +17691,38 @@ async function runServicesQuote(backend, serviceExecutionID, capabilityID, input
17449
17691
  __name(runServicesQuote, "runServicesQuote");
17450
17692
 
17451
17693
  // src/commands/services/purchase.ts
17452
- function invalid3() {
17453
- throw new CommandContractError("purchase_input_invalid", "purchase confirmation input is incomplete or invalid", "\u672C\u6B21\u672A\u53D1\u9001\u786E\u8BA4\u3002\u76F4\u63A5\u590D\u5236\u5F53\u524D\u5B8C\u6574 file_content\uFF1B\u6280\u672F\u5B57\u6BB5\u7531 Agent \u4FEE\u6B63\uFF0C\u53EA\u6709\u7F3A\u5931\u7684\u771F\u5B9E\u540C\u610F\u6216\u4EF7\u683C\u7EA6\u675F\u624D\u95EE\u7528\u6237\u3002", [], void 0, { request_sent: false });
17694
+ function invalid4(path3 = "input", allowed) {
17695
+ throw new CommandContractError("purchase_input_invalid", "purchase confirmation input is incomplete or invalid", "\u672C\u6B21\u672A\u53D1\u9001\u786E\u8BA4\u3002\u6309\u5F53\u524D confirmation_schema \u548C\u5B8C\u6574 file_content \u4FEE\u6B63\u6280\u672F\u5B57\u6BB5\uFF1B\u53EA\u6709\u7F3A\u5931\u7684\u771F\u5B9E\u540C\u610F\u6216\u4EF7\u683C\u51B3\u5B9A\u624D\u95EE\u7528\u6237\u3002", [], void 0, { request_sent: false, field: path3, ...allowed ? { allowed_values: allowed } : {} });
17454
17696
  }
17455
- __name(invalid3, "invalid");
17697
+ __name(invalid4, "invalid");
17456
17698
  function parsePurchaseConfirmation(raw) {
17457
- if (Object.keys(raw).some((key) => !["review_ref", "request_key", "user_approved", "user_answer", "price_policy"].includes(key))) invalid3();
17699
+ const keys = purchaseContract.required;
17700
+ for (const key of Object.keys(raw)) if (!keys.includes(key)) invalid4(key, keys);
17701
+ if (typeof raw.review_ref !== "string" || !raw.review_ref) invalid4("review_ref");
17702
+ if (typeof raw.request_key !== "string" || !raw.request_key || raw.request_key.length > purchaseContract.request_key_max_utf16_units) invalid4("request_key");
17703
+ if (raw.user_approved !== true) invalid4("user_approved", ["true"]);
17704
+ if (typeof raw.user_answer !== "string" || !raw.user_answer.trim()) invalid4("user_answer");
17458
17705
  const p = raw.price_policy;
17459
- if (typeof raw.review_ref !== "string" || !raw.review_ref || typeof raw.request_key !== "string" || !raw.request_key || raw.request_key.length > 200 || raw.user_approved !== true || typeof raw.user_answer !== "string" || !raw.user_answer.trim() || !p || typeof p !== "object" || Array.isArray(p)) invalid3();
17460
- if (!("mode" in p) || !("currency" in p) || typeof p.currency !== "string" || !p.currency || Object.keys(p).some((key) => !["mode", "currency", "amount_minor", "maximum_minor"].includes(key))) invalid3();
17461
- const safeAmount = /* @__PURE__ */ __name((n) => typeof n === "number" && Number.isSafeInteger(n) && n >= 0, "safeAmount");
17462
- if (p.mode === "exact" && "amount_minor" in p && safeAmount(p.amount_minor) && !("maximum_minor" in p)) return { review_ref: raw.review_ref, request_key: raw.request_key, user_approved: true, user_answer: raw.user_answer, price_policy: { mode: "exact", currency: p.currency, amount_minor: p.amount_minor } };
17463
- if (p.mode === "capped" && "maximum_minor" in p && safeAmount(p.maximum_minor) && !("amount_minor" in p)) return { review_ref: raw.review_ref, request_key: raw.request_key, user_approved: true, user_answer: raw.user_answer, price_policy: { mode: "capped", currency: p.currency, maximum_minor: p.maximum_minor } };
17464
- if (p.mode === "confirm_on_official_page" && !("amount_minor" in p) && !("maximum_minor" in p)) return { review_ref: raw.review_ref, request_key: raw.request_key, user_approved: true, user_answer: raw.user_answer, price_policy: { mode: "confirm_on_official_page", currency: p.currency } };
17465
- return invalid3();
17706
+ if (!p || typeof p !== "object" || Array.isArray(p)) invalid4("price_policy");
17707
+ if (!("mode" in p) || typeof p.mode !== "string" || !Object.hasOwn(purchaseContract.modes, p.mode)) invalid4("price_policy.mode", Object.keys(purchaseContract.modes));
17708
+ if (!("currency" in p) || typeof p.currency !== "string" || !p.currency) invalid4("price_policy.currency");
17709
+ const safeAmount = /* @__PURE__ */ __name((n) => typeof n === "number" && Number.isSafeInteger(n) && n >= 0 && n <= purchaseContract.amount_maximum, "safeAmount");
17710
+ const amountField = p.mode === "exact" ? purchaseContract.modes.exact : p.mode === "capped" ? purchaseContract.modes.capped : null;
17711
+ const allowedFields = ["mode", "currency", ...amountField ? [amountField] : []];
17712
+ for (const key of Object.keys(p)) if (!allowedFields.includes(key)) invalid4(`price_policy.${key}`, allowedFields);
17713
+ if (p.mode === "exact" && "amount_minor" in p && safeAmount(p.amount_minor)) return { review_ref: raw.review_ref, request_key: raw.request_key, user_approved: true, user_answer: raw.user_answer, price_policy: { mode: "exact", currency: p.currency, amount_minor: p.amount_minor } };
17714
+ if (p.mode === "capped" && "maximum_minor" in p && safeAmount(p.maximum_minor)) return { review_ref: raw.review_ref, request_key: raw.request_key, user_approved: true, user_answer: raw.user_answer, price_policy: { mode: "capped", currency: p.currency, maximum_minor: p.maximum_minor } };
17715
+ if (p.mode === "confirm_on_official_page") return { review_ref: raw.review_ref, request_key: raw.request_key, user_approved: true, user_answer: raw.user_answer, price_policy: { mode: "confirm_on_official_page", currency: p.currency } };
17716
+ return invalid4(`price_policy.${amountField}`);
17466
17717
  }
17467
17718
  __name(parsePurchaseConfirmation, "parsePurchaseConfirmation");
17468
17719
  async function runServicesPurchase(backend, config, id, input, options = {}) {
17469
17720
  const confirm = input ? parsePurchaseConfirmation(input) : void 0;
17470
- if (confirm && options.resume) invalid3();
17721
+ if (confirm && options.resume) invalid4();
17471
17722
  const contextError = validateContext(options.host ?? "terminal", options.target);
17472
17723
  if (contextError) throw new CommandContractError(contextError.code, contextError.message, "\u8865\u9F50\u5F53\u524D\u53EF\u4FE1 Host/target\uFF1B\u672C\u6B21\u672A\u53D1\u9001\u786E\u8BA4\u3002", [], void 0, { request_sent: false });
17473
17724
  const seconds = options.timeoutSeconds ?? 60;
17474
- if (!Number.isFinite(seconds) || seconds <= 0 || seconds > 120) invalid3();
17725
+ if (!Number.isFinite(seconds) || seconds <= 0 || seconds > 120) invalid4();
17475
17726
  let deadline = options.deadline ?? Date.now() + seconds * 1e3;
17476
17727
  let failureStage = confirm ? "confirm_purchase" : options.resume ? "resume_purchase" : "read_purchase_review";
17477
17728
  try {
@@ -17540,11 +17791,11 @@ __name(runAftercareRespond, "runAftercareRespond");
17540
17791
  import { rmSync } from "node:fs";
17541
17792
 
17542
17793
  // src/state/auth_storage.ts
17543
- import { createHash as createHash7 } from "node:crypto";
17544
- import { dirname as dirname4, resolve as resolve4 } from "node:path";
17545
- import { existsSync as existsSync4, mkdirSync as mkdirSync7, readFileSync as readFileSync8, renameSync as renameSync4, writeFileSync as writeFileSync6 } from "node:fs";
17794
+ import { createHash as createHash8 } from "node:crypto";
17795
+ import { dirname as dirname3, resolve as resolve4 } from "node:path";
17796
+ import { existsSync as existsSync4, mkdirSync as mkdirSync7, readFileSync as readFileSync8, renameSync as renameSync3, writeFileSync as writeFileSync6 } from "node:fs";
17546
17797
  function authStatePath(baseURL, env, purpose) {
17547
- return resolve4(stateDir(env), `${purpose}-${createHash7("sha256").update(baseURL).digest("hex").slice(0, 16)}.json`);
17798
+ return resolve4(stateDir(env), `${purpose}-${createHash8("sha256").update(baseURL).digest("hex").slice(0, 16)}.json`);
17548
17799
  }
17549
17800
  __name(authStatePath, "authStatePath");
17550
17801
  function readAuthState(baseURL, env, purpose) {
@@ -17557,10 +17808,10 @@ function readAuthState(baseURL, env, purpose) {
17557
17808
  __name(readAuthState, "readAuthState");
17558
17809
  function saveAuthState(state, env, purpose) {
17559
17810
  const path3 = authStatePath(state.baseURL, env, purpose);
17560
- mkdirSync7(dirname4(path3), { recursive: true, mode: 448 });
17811
+ mkdirSync7(dirname3(path3), { recursive: true, mode: 448 });
17561
17812
  const tmp = `${path3}.${process.pid}.tmp`;
17562
17813
  writeFileSync6(tmp, JSON.stringify(state), { mode: 384 });
17563
- renameSync4(tmp, path3);
17814
+ renameSync3(tmp, path3);
17564
17815
  }
17565
17816
  __name(saveAuthState, "saveAuthState");
17566
17817
 
@@ -18896,9 +19147,9 @@ var {
18896
19147
  } = import_index.default;
18897
19148
 
18898
19149
  // src/state/cart_session.ts
18899
- import { chmodSync as chmodSync2, existsSync as existsSync5, mkdirSync as mkdirSync8, readFileSync as readFileSync9, renameSync as renameSync5, writeFileSync as writeFileSync7 } from "node:fs";
18900
- import { randomUUID as randomUUID7 } from "node:crypto";
18901
- import { dirname as dirname5 } from "node:path";
19150
+ import { chmodSync as chmodSync2, existsSync as existsSync5, mkdirSync as mkdirSync8, readFileSync as readFileSync9, renameSync as renameSync4, writeFileSync as writeFileSync7 } from "node:fs";
19151
+ import { randomUUID as randomUUID8 } from "node:crypto";
19152
+ import { dirname as dirname4 } from "node:path";
18902
19153
  var CartSession = class _CartSession {
18903
19154
  static {
18904
19155
  __name(this, "CartSession");
@@ -18947,11 +19198,11 @@ var CartSession = class _CartSession {
18947
19198
  };
18948
19199
  const contents = JSON.stringify(toSave, null, 2);
18949
19200
  if (existsSync5(path3) && readFileSync9(path3, "utf-8") === contents) return;
18950
- mkdirSync8(dirname5(path3), { recursive: true, mode: 448 });
18951
- const temporary = `${path3}.${process.pid}.${randomUUID7()}.tmp`;
19201
+ mkdirSync8(dirname4(path3), { recursive: true, mode: 448 });
19202
+ const temporary = `${path3}.${process.pid}.${randomUUID8()}.tmp`;
18952
19203
  writeFileSync7(temporary, contents, { encoding: "utf-8", mode: 384 });
18953
19204
  chmodSync2(temporary, 384);
18954
- renameSync5(temporary, path3);
19205
+ renameSync4(temporary, path3);
18955
19206
  chmodSync2(path3, 384);
18956
19207
  }
18957
19208
  add(item) {
@@ -19075,6 +19326,8 @@ __name(versionParts, "versionParts");
19075
19326
 
19076
19327
  // src/commands/install.ts
19077
19328
  var INSTALL_AGENT_TYPES = [
19329
+ "dot",
19330
+ "muse",
19078
19331
  "codex-desktop",
19079
19332
  "codex-cli",
19080
19333
  "claude-code-desktop",
@@ -19083,10 +19336,14 @@ var INSTALL_AGENT_TYPES = [
19083
19336
  "zcode",
19084
19337
  "doubao-work",
19085
19338
  "kimi-code",
19086
- "openclaw"
19339
+ "openclaw",
19340
+ "hermes"
19087
19341
  ];
19088
19342
  var CODEX_WAIT_GUIDANCE = "Codex \u5BBF\u4E3B\u7B49\u5F85\uFF1A\u4FDD\u7559\u5B8C\u6574\u5DE5\u5177\u8FD4\u56DE\uFF0C\u6309\u5B9E\u9645\u8FD4\u56DE\u7684\u4F1A\u8BDD\u53E5\u67C4\u53CA\u5F53\u524D\u5BBF\u4E3B\u7EED\u8BFB\u5DE5\u5177\u6536\u53D6\u6700\u7EC8\u8F93\u51FA\uFF0C\u4E0D\u8981\u53EA\u53D6 stdout\u3002\u82E5\u4F7F\u7528 functions.exec \u5305\u88C5\uFF0C\u53EF\u7528 text(await tools.exec_command(...))\uFF1B\u5185\u5C42\u6709 session_id \u65F6\u7528 write_stdin\uFF0C\u5916\u5C42\u8FD4\u56DE\u8FD0\u884C cell \u65F6\u624D\u7528 wait\u3002\u6CA1\u6709\u8BE5\u5305\u88C5\u65F6\u6309\u5BBF\u4E3B\u5B9E\u9645\u5DE5\u5177\u64CD\u4F5C\u3002\u5148\u6536\u53D6\u6700\u7EC8\u8F93\u51FA\uFF0C\u518D\u6267\u884C CLI \u4E1A\u52A1 next\uFF1B\u4E0D\u8981\u91CD\u590D\u63D0\u4EA4\u3002";
19089
19343
  var INSTRUCTIONS = {
19344
+ hermes: "\u4FDD\u6301\u771F\u5B9E hermes Agent Type\uFF1B\u6309\u5F53\u524D\u5B9E\u9645\u5BBF\u4E3B\u5448\u73B0\u5B98\u65B9\u94FE\u63A5\uFF0C\u672A\u77E5\u663E\u793A\u80FD\u529B\u5982\u5B9E\u4FDD\u7559\u3002\u6CBF\u540C\u4E00 launcher\u3001Backend \u4E0E ITPAY_STATE_DIR \u6062\u590D\uFF0C\u4E0D\u5207\u6362\u8EAB\u4EFD\u6216\u91CD\u7F6E\u989D\u5EA6\u3002",
19345
+ dot: "\u4F7F\u7528\u771F\u5B9E dot \u7C7B\u578B\uFF1B\u4E91\u7AEF\u6267\u884C\u4F4D\u7F6E\u4E0E\u7528\u6237\u663E\u793A\u7AEF\u5206\u522B\u5224\u65AD\u3002\u5C55\u793A\u5B98\u65B9\u53EF\u70B9\u51FB\u94FE\u63A5\uFF0C\u4E8C\u7EF4\u7801\u53EF\u7528\u65F6\u589E\u5F3A\u5C55\u793A\uFF1B\u6D4F\u89C8\u5668\u6253\u5F00\u4E0D\u7B49\u4E8E\u7528\u6237\u5DF2\u770B\u5230\u3002\u540E\u7EED\u4FDD\u6301\u540C\u4E00 launcher\u3001Backend \u548C ITPAY_STATE_DIR\u3002",
19346
+ muse: "\u4F7F\u7528\u771F\u5B9E muse \u7C7B\u578B\uFF1B\u4FDD\u7559\u5BBF\u4E3B\u539F\u751F\u6279\u51C6\uFF0C\u4E0D\u7528\u804A\u5929\u540C\u610F\u66FF\u4EE3\u3002\u4E91\u7AEF\u53EF\u5199\u76EE\u5F55\u4E0D\u7B49\u4E8E\u8DE8\u4F1A\u8BDD\u6301\u4E45\uFF0C\u663E\u793A\u80FD\u529B\u672A\u77E5\u65F6\u5982\u5B9E\u62A5\u544A\uFF1B\u6CBF\u540C\u4E00 launcher\u3001Backend \u548C ITPAY_STATE_DIR \u6062\u590D\u539F\u4EFB\u52A1\u3002",
19090
19347
  "codex-desktop": "\u5728 Codex Desktop \u4E2D\u59CB\u7EC8\u4F20\u8FD9\u4E2A Agent Type\uFF1B\u4ED8\u6B3E\u65F6\u628A\u8FD4\u56DE\u7684\u4E8C\u7EF4\u7801\u548C\u94FE\u63A5\u5B9E\u9645\u5C55\u793A\u5230\u5F53\u524D\u5BF9\u8BDD\u3002",
19091
19348
  "codex-cli": "\u5728 Codex CLI \u4E2D\u59CB\u7EC8\u4F20\u8FD9\u4E2A Agent Type\uFF1B\u4ED8\u6B3E\u4EA4\u63A5\u53EA\u5E94\u663E\u793A\u5728\u7528\u6237\u53EF\u89C1\u7EC8\u7AEF\u3002",
19092
19349
  "claude-code-desktop": "\u5728 Claude Code Desktop \u4E2D\u59CB\u7EC8\u4F20\u8FD9\u4E2A Agent Type\uFF1B\u4ED8\u6B3E\u65F6\u628A\u8FD4\u56DE\u7684\u4E8C\u7EF4\u7801\u548C\u94FE\u63A5\u5B9E\u9645\u5C55\u793A\u5230\u5F53\u524D\u5BF9\u8BDD\u3002",
@@ -19148,17 +19405,23 @@ function installDefinition(agentType) {
19148
19405
  }
19149
19406
  __name(installDefinition, "installDefinition");
19150
19407
 
19408
+ // src/commands/skill.ts
19409
+ import { createHash as createHash9 } from "node:crypto";
19410
+
19411
+ // src/state/skill_identity.generated.ts
19412
+ var CANONICAL_SKILL_SHA256 = "9e36b56ef726cd1c7db603474fb977fa3cc5b84ef6b005d007e9f322ac534ce7";
19413
+
19151
19414
  // src/commands/skill.ts
19152
19415
  import { existsSync as existsSync7, readFileSync as readFileSync11 } from "node:fs";
19153
19416
  import { resolve as resolve6 } from "node:path";
19154
19417
 
19155
19418
  // src/state/package_resources.ts
19156
19419
  import { existsSync as existsSync6, readFileSync as readFileSync10 } from "node:fs";
19157
- import { basename as basename2, dirname as dirname6, resolve as resolve5 } from "node:path";
19420
+ import { basename as basename2, dirname as dirname5, resolve as resolve5 } from "node:path";
19158
19421
  import { fileURLToPath } from "node:url";
19159
19422
  function packageResourcePath(...segments) {
19160
19423
  const modulePath = fileURLToPath(import.meta.url);
19161
- const root = resolve5(dirname6(modulePath), "..", "..");
19424
+ const root = resolve5(dirname5(modulePath), "..", "..");
19162
19425
  if (!basename2(modulePath).startsWith("package_resources.") && basename2(modulePath) !== "main.js") throw new Error("unsupported CLI resource layout");
19163
19426
  const metadata = resolve5(root, "package.json");
19164
19427
  if (!existsSync6(metadata) || JSON.parse(readFileSync10(metadata, "utf8")).name !== "@itpay/cli") throw new Error("current CLI package resources are unavailable");
@@ -19170,7 +19433,7 @@ __name(packageResourcePath, "packageResourcePath");
19170
19433
  var ITPAY_SKILL = "itpay";
19171
19434
  function runSkillShow(name, options = {}) {
19172
19435
  const normalized = name.trim().toLowerCase();
19173
- if (normalized !== ITPAY_SKILL) {
19436
+ if (normalized !== ITPAY_SKILL && normalized !== "itpay-buyer") {
19174
19437
  throw new CommandContractError(
19175
19438
  "skill_not_found",
19176
19439
  `skill not found: ${name}`,
@@ -19228,8 +19491,12 @@ ${CODEX_WAIT_GUIDANCE}
19228
19491
  }
19229
19492
  __name(runSkillShow, "runSkillShow");
19230
19493
  function packagedSkill() {
19231
- const path3 = findSkillPath(false);
19494
+ let path3 = findSkillPath(false);
19495
+ if (!existsSync7(path3) && process.env.ITPAY_CLI_SKILLS_DIR) path3 = findSkillPath();
19232
19496
  const content = readFileSync11(path3, "utf8");
19497
+ if (createHash9("sha256").update(content).digest("hex") !== CANONICAL_SKILL_SHA256) {
19498
+ throw new CommandContractError("skill_override_mismatch", "Skill does not match this pinned CLI build", "\u4F7F\u7528\u5F53\u524D\u5305\u540C\u6E90\u7684\u5B8C\u6574 Skill\uFF1B\u4FDD\u7559\u539F\u4EFB\u52A1\u548C\u8EAB\u4EFD\uFF0C\u4E0D\u5B89\u88C5\u53E6\u4E00\u5957 CLI\u3002", []);
19499
+ }
19233
19500
  validateSkill(content);
19234
19501
  return { path: path3, content };
19235
19502
  }
@@ -19297,6 +19564,13 @@ async function runSetup(backend, config, skillPath, options = {}) {
19297
19564
  cli_version: CLI_VERSION2,
19298
19565
  backend_url: config.baseURL,
19299
19566
  agent_type: config.agentType,
19567
+ state_directory: stateDir(),
19568
+ state_persistence: "unverified_across_sessions",
19569
+ skill_readable: true,
19570
+ skill_written: "unknown",
19571
+ skill_discoverable: "unknown",
19572
+ execution_position: "unknown",
19573
+ presentation_surface: "unknown",
19300
19574
  device_status: "ready",
19301
19575
  account_status: account.status,
19302
19576
  skill_path: skillPath,
@@ -19745,63 +20019,6 @@ function formatProductMoney(amountMinor, currency) {
19745
20019
  }
19746
20020
  __name(formatProductMoney, "formatProductMoney");
19747
20021
 
19748
- // src/render/browser.ts
19749
- import { spawn } from "node:child_process";
19750
- import { platform } from "node:os";
19751
- function isPresentableURL(raw, baseURL, env = process.env) {
19752
- let url;
19753
- try {
19754
- url = new URL(raw);
19755
- } catch {
19756
- return false;
19757
- }
19758
- if (url.username || url.password) return false;
19759
- if (env.ITPAY_CLI_DEV === "1" && /^http:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/.test(url.origin)) return true;
19760
- if (url.protocol !== "https:") return false;
19761
- const allowedOrigins = /* @__PURE__ */ new Set(["https://app.itpay.ai", "https://sandbox.itpay.ai", "https://dev.itpay.ai"]);
19762
- if (baseURL) {
19763
- try {
19764
- allowedOrigins.add(new URL(baseURL).origin);
19765
- } catch {
19766
- }
19767
- }
19768
- return allowedOrigins.has(url.origin);
19769
- }
19770
- __name(isPresentableURL, "isPresentableURL");
19771
- function openInSystemBrowser(raw, baseURL, env = process.env) {
19772
- if (!isPresentableURL(raw, baseURL, env)) {
19773
- return Promise.resolve({ status: "failed", reason: "url_rejected" });
19774
- }
19775
- const [command, args] = openerArgv(raw);
19776
- if (!command) {
19777
- return Promise.resolve({ status: "unavailable", reason: "no system opener on this platform" });
19778
- }
19779
- return new Promise((resolvePromise) => {
19780
- const child = spawn(command, args, { detached: true, stdio: "ignore" });
19781
- child.once("error", (error) => resolvePromise({ status: "failed", reason: error.message }));
19782
- child.once("spawn", () => {
19783
- child.unref();
19784
- resolvePromise({ status: "dispatch_accepted", argv: [command, ...args] });
19785
- });
19786
- });
19787
- }
19788
- __name(openInSystemBrowser, "openInSystemBrowser");
19789
- function openerArgv(url) {
19790
- switch (platform()) {
19791
- case "darwin":
19792
- return ["open", [url]];
19793
- case "win32":
19794
- return ["cmd.exe", ["/c", "start", "", url]];
19795
- case "linux":
19796
- case "freebsd":
19797
- case "openbsd":
19798
- return ["xdg-open", [url]];
19799
- default:
19800
- return [void 0, []];
19801
- }
19802
- }
19803
- __name(openerArgv, "openerArgv");
19804
-
19805
20022
  // src/commands/presentation.ts
19806
20023
  var yes = /* @__PURE__ */ __name((value) => value === "yes", "yes");
19807
20024
  function resolvePresentation(input) {
@@ -21385,7 +21602,7 @@ function writeCartNextEnvelope(envelope, options) {
21385
21602
  __name(writeCartNextEnvelope, "writeCartNextEnvelope");
21386
21603
 
21387
21604
  // src/commands/docs.ts
21388
- import { readFileSync as readFileSync12, readdirSync as readdirSync3 } from "node:fs";
21605
+ import { readFileSync as readFileSync12, readdirSync as readdirSync4 } from "node:fs";
21389
21606
  import { resolve as resolve7 } from "node:path";
21390
21607
  function runDocsList(options = {}) {
21391
21608
  const topics = loadDocs().map(({ topic, title, purpose }) => ({ topic, title, purpose }));
@@ -21460,11 +21677,11 @@ function runDocsSearch(query, options = {}) {
21460
21677
  __name(runDocsSearch, "runDocsSearch");
21461
21678
  function loadDocs() {
21462
21679
  const docsDir = findDocsDir();
21463
- const files = readdirSync3(docsDir).filter((file) => file.endsWith(".json")).sort();
21680
+ const files = readdirSync4(docsDir).filter((file) => file.endsWith(".json")).sort();
21464
21681
  const docs = files.map((file) => parseDoc(readFileSync12(resolve7(docsDir, file), "utf8"), file));
21465
21682
  if (process.env.ITPAY_CLI_DOCS_DIR) {
21466
21683
  const canonical = packageResourcePath("docs", "agent", "buyer");
21467
- const expectedFiles = readdirSync3(canonical).filter((file) => file.endsWith(".json")).sort();
21684
+ const expectedFiles = readdirSync4(canonical).filter((file) => file.endsWith(".json")).sort();
21468
21685
  if (JSON.stringify(files) !== JSON.stringify(expectedFiles) || files.some((file, index) => JSON.stringify(docs[index]) !== JSON.stringify(parseDoc(readFileSync12(resolve7(canonical, file), "utf8"), file)))) {
21469
21686
  throw new CommandContractError(
21470
21687
  "docs_override_mismatch",
@@ -21609,11 +21826,11 @@ function parseRequiredContactFields(value) {
21609
21826
  return void 0;
21610
21827
  }
21611
21828
  const values = value.split(",").map((item) => item.trim().toLowerCase()).filter(Boolean);
21612
- const invalid4 = values.filter((item) => item !== "email" && item !== "phone");
21613
- if (invalid4.length > 0) {
21829
+ const invalid5 = values.filter((item) => item !== "email" && item !== "phone");
21830
+ if (invalid5.length > 0) {
21614
21831
  throw new CommandContractError(
21615
21832
  "contact_field_invalid",
21616
- `unsupported required contact fields: ${invalid4.join(", ")}`,
21833
+ `unsupported required contact fields: ${invalid5.join(", ")}`,
21617
21834
  "--require-contact \u53EA\u63A5\u53D7 email\u3001phone \u6216\u4E8C\u8005\u7EC4\u5408\u3002",
21618
21835
  [{ command: "itpay buy --help", reason: "\u67E5\u770B contact \u53C2\u6570" }]
21619
21836
  );
@@ -21623,8 +21840,8 @@ function parseRequiredContactFields(value) {
21623
21840
  }
21624
21841
  __name(parseRequiredContactFields, "parseRequiredContactFields");
21625
21842
  function positiveInteger(value, name) {
21626
- const text = String(value ?? "");
21627
- if (!/^[1-9]\d*$/.test(text)) {
21843
+ const text2 = String(value ?? "");
21844
+ if (!/^[1-9]\d*$/.test(text2)) {
21628
21845
  throw new CommandContractError(
21629
21846
  "buy_parameter_invalid",
21630
21847
  `${name} must be a positive integer`,
@@ -21632,7 +21849,7 @@ function positiveInteger(value, name) {
21632
21849
  [{ command: "itpay buy --help", reason: "\u67E5\u770B\u53C2\u6570\u683C\u5F0F" }]
21633
21850
  );
21634
21851
  }
21635
- return Number(text);
21852
+ return Number(text2);
21636
21853
  }
21637
21854
  __name(positiveInteger, "positiveInteger");
21638
21855
  function resolveCheckoutPresentationArgs(input) {
@@ -21723,14 +21940,14 @@ function reportCLIError(error, contract) {
21723
21940
  } : {}
21724
21941
  }
21725
21942
  } : {},
21726
- instruction: incompatible ? "\u5F53\u524D CLI \u4E0E Backend \u5408\u7EA6\u4E0D\u517C\u5BB9\u6216\u65E0\u6CD5\u6838\u9A8C\u3002minimum_cli_version \u4EC5\u662F\u534F\u8BAE\u95E8\u69DB\uFF0C\u4E0D\u662F\u5DF2\u9A8C\u8BC1\u7684\u63A8\u8350\u5B89\u88C5\u5305\u3002\u505C\u6B62\u672C\u8F6E\uFF0C\u8BF7\u7EF4\u62A4\u65B9\u63D0\u4F9B\u4E0E\u5F53\u524D Backend \u914D\u5957\u7684\u5236\u54C1\uFF1B\u4E0D\u8981\u731C\u7248\u672C\u3001\u964D\u7EA7\u3001\u5207\u6362 Agent Type \u6216\u5220\u9664 Device \u8EAB\u4EFD\u3002" : backendInternal ? "\u544A\u8BC9\u7528\u6237 ItPay \u5F53\u524D\u6682\u65F6\u65E0\u6CD5\u5B8C\u6210\u8FD9\u9879\u670D\u52A1\u5E76\u505C\u6B62\u3002\u4E0D\u8981\u8F6C\u8FF0\u5185\u90E8\u9519\u8BEF\u3001\u91CD\u8BD5\u3001\u4FEE\u6539\u8EAB\u4EFD\u3001\u521B\u5EFA\u66FF\u4EE3\u670D\u52A1\u6216\u8FDB\u5165\u4EFB\u4F55\u4ED8\u8D39\u8DEF\u5F84\u3002" : providerConnectionUnavailable ? "\u544A\u8BC9\u7528\u6237\u672C\u6B21\u67E5\u8BE2\u6CA1\u6709\u53D1\u9001\u5230\u6570\u636E\u6765\u6E90\uFF0C\u514D\u8D39\u989D\u5EA6\u5DF2\u4FDD\u7559\uFF0C\u7136\u540E\u505C\u6B62\u3002\u4E0D\u8981\u8F6C\u8FF0\u6280\u672F\u9519\u8BEF\u3001\u81EA\u52A8\u91CD\u8BD5\u6216\u8FDB\u5165\u4ED8\u8D39\u8DEF\u5F84\uFF1B\u53EA\u6709\u670D\u52A1\u6062\u590D\u4E14\u7528\u6237\u660E\u786E\u8981\u6C42\u91CD\u65B0\u67E5\u8BE2\u540E\u624D\u80FD\u5F00\u59CB\u65B0\u7684\u67E5\u8BE2\u3002" : providerTemporary ? "\u544A\u8BC9\u7528\u6237\u6570\u636E\u670D\u52A1\u6682\u65F6\u4E0D\u53EF\u7528\uFF0C\u5E76\u6309 result.quota \u8BF4\u660E\u989D\u5EA6\u662F\u5426\u4FDD\u7559\uFF0C\u7136\u540E\u505C\u6B62\u3002\u4E0D\u8981\u8F6C\u8FF0\u6280\u672F\u9519\u8BEF\u3001\u81EA\u52A8\u91CD\u8BD5\u6216\u521B\u5EFA\u65B0\u67E5\u8BE2\uFF1B\u53EA\u6709\u7528\u6237\u4E4B\u540E\u660E\u786E\u63D0\u51FA\u65B0\u8BF7\u6C42\u624D\u53EF\u91CD\u65B0\u5F00\u59CB\u3002" : providerInputRejected ? "\u544A\u8BC9\u7528\u6237\u6570\u636E\u6765\u6E90\u660E\u786E\u8868\u793A\u5F53\u524D\u8F93\u5165\u65E0\u6548\uFF0C\u5E76\u6309 result.quota \u8BF4\u660E\u989D\u5EA6\u72B6\u6001\uFF0C\u7136\u540E\u505C\u6B62\u3002\u4E0D\u8981\u8F6C\u8FF0\u5185\u90E8\u9519\u8BEF\u3001\u81EA\u884C\u4FEE\u6539\u8F93\u5165\u3001\u91CD\u8BD5\u6216\u521B\u5EFA\u65B0\u67E5\u8BE2\uFF1B\u53EA\u6709\u7528\u6237\u660E\u786E\u63D0\u4F9B\u65B0\u8F93\u5165\u540E\u624D\u80FD\u91CD\u65B0\u67E5\u8BE2\u3002" : providerContractMismatch ? "\u544A\u8BC9\u7528\u6237\u5E73\u53F0\u6682\u65F6\u65E0\u6CD5\u6B63\u786E\u89E3\u91CA\u6570\u636E\u6765\u6E90\u7684\u54CD\u5E94\uFF0C\u8FD9\u4E0D\u662F\u7528\u6237\u8F93\u5165\u95EE\u9898\uFF0C\u5E76\u6309 result.quota \u8BF4\u660E\u989D\u5EA6\u72B6\u6001\u3002\u7ACB\u5373\u505C\u6B62\uFF0C\u4E0D\u8981\u4FEE\u6539\u8F93\u5165\u3001\u91CD\u8BD5\u3001\u521B\u5EFA\u65B0\u67E5\u8BE2\u6216\u8FDB\u5165\u4ED8\u8D39\u8DEF\u5F84\u3002" : providerRejected ? "\u544A\u8BC9\u7528\u6237\u6570\u636E\u6765\u6E90\u6CA1\u6709\u63A5\u53D7\u672C\u6B21\u8BF7\u6C42\uFF0C\u4F46\u6CA1\u6709\u8BF4\u660E\u662F\u8F93\u5165\u9519\u8BEF\uFF0C\u5E76\u6309 result.quota \u8BF4\u660E\u989D\u5EA6\u72B6\u6001\uFF0C\u7136\u540E\u505C\u6B62\u3002\u4E0D\u8981\u8F6C\u8FF0\u5185\u90E8\u9519\u8BEF\u3001\u4FEE\u6539\u8F93\u5165\u3001\u91CD\u8BD5\u6216\u521B\u5EFA\u65B0\u67E5\u8BE2\u3002" : capabilityInputInvalid ? "Agent\u6309\u5F53\u524D\u5408\u540C\u6A21\u677F\u4FEE\u6B63\u5B57\u6BB5\u548CJSON\u5C42\u7EA7\uFF0C\u4FDD\u7559\u7528\u6237\u539F\u59CB\u9700\u6C42\uFF0C\u7EE7\u7EED\u540C\u4E00\u6B21\u670D\u52A1\u3002\u4E0D\u8981\u8BA9\u7528\u6237\u4FEE\u6280\u672F\u8F93\u5165\uFF0C\u53EA\u6709\u771F\u5B9E\u4E1A\u52A1\u6B67\u4E49\u624D\u8BE2\u95EE\u3002" : transportError ? contract?.initialization ? "\u672C\u8F6E\u521D\u59CB\u5316\u68C0\u67E5\u672A\u5B8C\u6210\uFF1BCLI \u5DF2\u7ED3\u675F\u6709\u9650\u7684\u7F51\u7EDC\u5C1D\u8BD5\uFF0C\u5C1A\u672A\u786E\u8BA4\u540E\u7AEF\u6216\u8BBE\u5907\u5C31\u7EEA\u3002\u7ED3\u675F\u672C\u8F6E\uFF0C\u7F51\u7EDC\u6062\u590D\u540E\u53EF\u91CD\u65B0\u68C0\u67E5\uFF1B\u4E0D\u8981\u7EE7\u7EED\u767B\u5F55\u6216\u4E1A\u52A1\u64CD\u4F5C\u3002" : transportError.attempts > 1 ? "\u4E34\u65F6\u7F51\u7EDC\u6545\u969C\uFF1BCLI \u5DF2\u4EC5\u5BF9\u53EF\u5B89\u5168\u91CD\u653E\u7684\u64CD\u4F5C\u5B8C\u6210\u6709\u9650\u81EA\u52A8\u91CD\u8BD5\uFF0C\u4F46\u4ECD\u672A\u83B7\u5F97\u5B8C\u6574\u54CD\u5E94\u3002\u6309 recovery \u67E5\u8BE2\u540C\u4E00\u8D44\u6E90\u7684\u6743\u5A01\u72B6\u6001\uFF1B\u4E0D\u8981\u521B\u5EFA\u66FF\u4EE3 Checkout\u3001Execution\u3001Payment \u6216 Refund\u3002" : "\u7F51\u7EDC\u5728\u5B8C\u6574\u54CD\u5E94\u524D\u4E2D\u65AD\uFF1B\u5F53\u524D\u5199\u64CD\u4F5C\u6CA1\u6709\u5B89\u5168\u91CD\u653E\u5408\u540C\uFF0C\u56E0\u6B64 CLI \u672A\u81EA\u52A8\u91CD\u8BD5\u3002\u6309 recovery \u67E5\u8BE2\u6743\u5A01\u72B6\u6001\uFF1B\u4E0D\u8981\u539F\u6837\u91CD\u653E\u6216\u521B\u5EFA\u66FF\u4EE3 Checkout\u3001Execution\u3001Payment \u6216 Refund\u3002" : backendOverrideError ? "\u79FB\u9664 ITPAY_BACKEND_URL \u4F7F\u7528\u6B63\u5F0F\u73AF\u5883\uFF0C\u6216\u6309\u5F53\u524D\u6D4B\u8BD5\u76EE\u6807\u51C6\u786E\u8BBE\u7F6E\u4E3A https://sandbox.itpay.ai \u6216 https://dev.itpay.ai\u3002\u4E0D\u8981\u901A\u8FC7\u5207\u6362\u73AF\u5883\u89C4\u907F\u5F53\u524D\u9519\u8BEF\u3002" : commandError?.instruction ?? authorizationInstruction ?? contract?.instruction ?? "\u68C0\u67E5\u547D\u4EE4\u53C2\u6570\u540E\u91CD\u8BD5\u3002",
21943
+ instruction: incompatible ? "\u5F53\u524D CLI \u4E0E Backend \u5408\u7EA6\u4E0D\u517C\u5BB9\u6216\u65E0\u6CD5\u6838\u9A8C\u3002minimum_cli_version \u4EC5\u662F\u534F\u8BAE\u95E8\u69DB\uFF0C\u4E0D\u662F\u5DF2\u9A8C\u8BC1\u7684\u63A8\u8350\u5B89\u88C5\u5305\u3002\u505C\u6B62\u672C\u8F6E\uFF0C\u8BF7\u7EF4\u62A4\u65B9\u63D0\u4F9B\u4E0E\u5F53\u524D Backend \u914D\u5957\u7684\u5236\u54C1\uFF1B\u4E0D\u8981\u731C\u7248\u672C\u3001\u964D\u7EA7\u3001\u5207\u6362 Agent Type \u6216\u5220\u9664 Device \u8EAB\u4EFD\u3002" : backendInternal ? "\u544A\u8BC9\u7528\u6237 ItPay \u5F53\u524D\u6682\u65F6\u65E0\u6CD5\u5B8C\u6210\u8FD9\u9879\u670D\u52A1\u5E76\u505C\u6B62\u3002\u4E0D\u8981\u8F6C\u8FF0\u5185\u90E8\u9519\u8BEF\u3001\u91CD\u8BD5\u3001\u4FEE\u6539\u8EAB\u4EFD\u3001\u521B\u5EFA\u66FF\u4EE3\u670D\u52A1\u6216\u8FDB\u5165\u4EFB\u4F55\u4ED8\u8D39\u8DEF\u5F84\u3002" : providerConnectionUnavailable ? "\u544A\u8BC9\u7528\u6237\u672C\u6B21\u67E5\u8BE2\u6CA1\u6709\u53D1\u9001\u5230\u6570\u636E\u6765\u6E90\uFF0C\u514D\u8D39\u989D\u5EA6\u5DF2\u4FDD\u7559\uFF0C\u7136\u540E\u505C\u6B62\u3002\u4E0D\u8981\u8F6C\u8FF0\u6280\u672F\u9519\u8BEF\u3001\u81EA\u52A8\u91CD\u8BD5\u6216\u8FDB\u5165\u4ED8\u8D39\u8DEF\u5F84\uFF1B\u53EA\u6709\u670D\u52A1\u6062\u590D\u4E14\u7528\u6237\u660E\u786E\u8981\u6C42\u91CD\u65B0\u67E5\u8BE2\u540E\u624D\u80FD\u5F00\u59CB\u65B0\u7684\u67E5\u8BE2\u3002" : providerTemporary ? "\u544A\u8BC9\u7528\u6237\u6570\u636E\u670D\u52A1\u6682\u65F6\u4E0D\u53EF\u7528\uFF0C\u5E76\u6309 result.quota \u8BF4\u660E\u989D\u5EA6\u662F\u5426\u4FDD\u7559\uFF0C\u7136\u540E\u505C\u6B62\u3002\u4E0D\u8981\u8F6C\u8FF0\u6280\u672F\u9519\u8BEF\u3001\u81EA\u52A8\u91CD\u8BD5\u6216\u521B\u5EFA\u65B0\u67E5\u8BE2\uFF1B\u53EA\u6709\u7528\u6237\u4E4B\u540E\u660E\u786E\u63D0\u51FA\u65B0\u8BF7\u6C42\u624D\u53EF\u91CD\u65B0\u5F00\u59CB\u3002" : providerInputRejected ? "\u544A\u8BC9\u7528\u6237\u6570\u636E\u6765\u6E90\u660E\u786E\u8868\u793A\u5F53\u524D\u8F93\u5165\u65E0\u6548\uFF0C\u5E76\u6309 result.quota \u8BF4\u660E\u989D\u5EA6\u72B6\u6001\uFF0C\u7136\u540E\u505C\u6B62\u3002\u4E0D\u8981\u8F6C\u8FF0\u5185\u90E8\u9519\u8BEF\u3001\u81EA\u884C\u4FEE\u6539\u8F93\u5165\u3001\u91CD\u8BD5\u6216\u521B\u5EFA\u65B0\u67E5\u8BE2\uFF1B\u53EA\u6709\u7528\u6237\u660E\u786E\u63D0\u4F9B\u65B0\u8F93\u5165\u540E\u624D\u80FD\u91CD\u65B0\u67E5\u8BE2\u3002" : providerContractMismatch ? "\u544A\u8BC9\u7528\u6237\u5E73\u53F0\u6682\u65F6\u65E0\u6CD5\u6B63\u786E\u89E3\u91CA\u6570\u636E\u6765\u6E90\u7684\u54CD\u5E94\uFF0C\u8FD9\u4E0D\u662F\u7528\u6237\u8F93\u5165\u95EE\u9898\uFF0C\u5E76\u6309 result.quota \u8BF4\u660E\u989D\u5EA6\u72B6\u6001\u3002\u7ACB\u5373\u505C\u6B62\uFF0C\u4E0D\u8981\u4FEE\u6539\u8F93\u5165\u3001\u91CD\u8BD5\u3001\u521B\u5EFA\u65B0\u67E5\u8BE2\u6216\u8FDB\u5165\u4ED8\u8D39\u8DEF\u5F84\u3002" : providerRejected ? "\u544A\u8BC9\u7528\u6237\u6570\u636E\u6765\u6E90\u6CA1\u6709\u63A5\u53D7\u672C\u6B21\u8BF7\u6C42\uFF0C\u4F46\u6CA1\u6709\u8BF4\u660E\u662F\u8F93\u5165\u9519\u8BEF\uFF0C\u5E76\u6309 result.quota \u8BF4\u660E\u989D\u5EA6\u72B6\u6001\uFF0C\u7136\u540E\u505C\u6B62\u3002\u4E0D\u8981\u8F6C\u8FF0\u5185\u90E8\u9519\u8BEF\u3001\u4FEE\u6539\u8F93\u5165\u3001\u91CD\u8BD5\u6216\u521B\u5EFA\u65B0\u67E5\u8BE2\u3002" : capabilityInputInvalid ? "Agent\u6309\u5F53\u524D\u5408\u540C\u6A21\u677F\u4FEE\u6B63\u5B57\u6BB5\u548CJSON\u5C42\u7EA7\uFF0C\u4FDD\u7559\u7528\u6237\u539F\u59CB\u9700\u6C42\uFF0C\u7EE7\u7EED\u540C\u4E00\u6B21\u670D\u52A1\u3002\u4E0D\u8981\u8BA9\u7528\u6237\u4FEE\u6280\u672F\u8F93\u5165\uFF0C\u53EA\u6709\u771F\u5B9E\u4E1A\u52A1\u6B67\u4E49\u624D\u8BE2\u95EE\u3002" : transportError ? contract?.initialization ? "\u672C\u8F6E\u521D\u59CB\u5316\u68C0\u67E5\u672A\u5B8C\u6210\uFF1BCLI \u5DF2\u7ED3\u675F\u6709\u9650\u7684\u7F51\u7EDC\u5C1D\u8BD5\uFF0C\u5C1A\u672A\u786E\u8BA4\u540E\u7AEF\u6216\u8BBE\u5907\u5C31\u7EEA\u3002\u7ED3\u675F\u672C\u8F6E\uFF0C\u7F51\u7EDC\u6062\u590D\u540E\u53EF\u91CD\u65B0\u68C0\u67E5\uFF1B\u4E0D\u8981\u7EE7\u7EED\u767B\u5F55\u6216\u4E1A\u52A1\u64CD\u4F5C\u3002" : transportError.attempts > 1 ? "\u4E34\u65F6\u7F51\u7EDC\u6545\u969C\uFF1BCLI \u5DF2\u4EC5\u5BF9\u53EF\u5B89\u5168\u91CD\u653E\u7684\u64CD\u4F5C\u5B8C\u6210\u6709\u9650\u81EA\u52A8\u91CD\u8BD5\uFF0C\u4F46\u4ECD\u672A\u83B7\u5F97\u5B8C\u6574\u54CD\u5E94\u3002\u6309 recovery \u67E5\u8BE2\u540C\u4E00\u8D44\u6E90\u7684\u6743\u5A01\u72B6\u6001\uFF1B\u4E0D\u8981\u521B\u5EFA\u66FF\u4EE3 Checkout\u3001Execution\u3001Payment \u6216 Refund\u3002" : "\u7F51\u7EDC\u5728\u5B8C\u6574\u54CD\u5E94\u524D\u4E2D\u65AD\uFF1B\u5F53\u524D\u5199\u64CD\u4F5C\u6CA1\u6709\u5B89\u5168\u91CD\u653E\u5408\u540C\uFF0C\u56E0\u6B64 CLI \u672A\u81EA\u52A8\u91CD\u8BD5\u3002\u6309 recovery \u67E5\u8BE2\u6743\u5A01\u72B6\u6001\uFF1B\u4E0D\u8981\u539F\u6837\u91CD\u653E\u6216\u521B\u5EFA\u66FF\u4EE3 Checkout\u3001Execution\u3001Payment \u6216 Refund\u3002" : backendOverrideError ? "\u79FB\u9664 ITPAY_BACKEND_URL \u4F7F\u7528\u6B63\u5F0F\u73AF\u5883\uFF0C\u6216\u6309\u5F53\u524D\u6D4B\u8BD5\u76EE\u6807\u51C6\u786E\u8BBE\u7F6E\u4E3A https://sandbox.itpay.ai \u3001https://dev.itpay.ai \u6216 https://v4-dev.itpay.ai\u3002\u4E0D\u8981\u901A\u8FC7\u5207\u6362\u73AF\u5883\u89C4\u907F\u5F53\u524D\u9519\u8BEF\u3002" : commandError?.instruction ?? authorizationInstruction ?? contract?.instruction ?? "\u68C0\u67E5\u547D\u4EE4\u53C2\u6570\u540E\u91CD\u8BD5\u3002",
21727
21944
  next: null,
21728
21945
  ...commandError?.interaction ? { interaction: commandError.interaction } : {},
21729
21946
  recovery: incompatible || transportError && contract?.initialization ? [] : backendInternal || providerConnectionUnavailable || providerTemporary || providerInputRejected || providerContractMismatch || providerRejected || capabilityInputInvalid ? [] : backendOverrideError ? [] : commandError?.recovery ?? (stateError ? stateRecovery : deviceError ? deviceRecovery : identityRecovery ? httpRecovery : contract?.recovery ?? [])
21730
21947
  }, {
21731
21948
  ...contract?.jsonOutput !== void 0 ? { jsonOutput: contract.jsonOutput } : backendOverrideError || stateError ? { jsonOutput: process.argv.includes("--json") } : {},
21732
- output: /* @__PURE__ */ __name((text) => {
21733
- process.stdout.write(text);
21949
+ output: /* @__PURE__ */ __name((text2) => {
21950
+ process.stdout.write(text2);
21734
21951
  }, "output")
21735
21952
  });
21736
21953
  process.exitCode = 1;
@@ -21739,7 +21956,7 @@ function reportCLIError(error, contract) {
21739
21956
  if (error instanceof HttpError) {
21740
21957
  process.stderr.write(`[${error.status}] ${error.code}: ${error.message}
21741
21958
  `);
21742
- printErrorRecovery(error, (text) => process.stderr.write(text));
21959
+ printErrorRecovery(error, (text2) => process.stderr.write(text2));
21743
21960
  process.exitCode = 1;
21744
21961
  return;
21745
21962
  }