@itpay/cli 2.1.60 → 2.1.61
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 +114 -49
- package/dist/src/state/config.js +1 -1
- package/package.json +2 -2
- package/skills/itpay-api/SKILL.md +2 -0
package/dist/src/main.js
CHANGED
|
@@ -3841,7 +3841,8 @@ __name(withAsyncFileLock, "withAsyncFileLock");
|
|
|
3841
3841
|
import { createHash, randomBytes } from "node:crypto";
|
|
3842
3842
|
import { createServer } from "node:http";
|
|
3843
3843
|
function hubOAuthConfig(env = process.env) {
|
|
3844
|
-
const
|
|
3844
|
+
const devHub = (env.ITPAY_HUB_URL ?? "").replace(/\/+$/, "") === "https://market-v4-dev.itpay.ai";
|
|
3845
|
+
const issuer = (env.ITPAY_HUB_OAUTH_ISSUER ?? (devHub ? "https://auth-v4-dev.itpay.ai" : "http://localhost:24444")).replace(/\/+$/, "");
|
|
3845
3846
|
return {
|
|
3846
3847
|
authorizeURL: `${issuer}/oauth2/auth`,
|
|
3847
3848
|
tokenURL: `${issuer}/oauth2/token`,
|
|
@@ -5568,6 +5569,26 @@ __name(renderPaymentHandoff, "renderPaymentHandoff");
|
|
|
5568
5569
|
|
|
5569
5570
|
// src/commands/hub_guidance.ts
|
|
5570
5571
|
function writeCommandEnvelope(value, options = {}) {
|
|
5572
|
+
const qualify = /* @__PURE__ */ __name((action) => {
|
|
5573
|
+
if (!action.command.startsWith("itpay ")) return action;
|
|
5574
|
+
const assignments = [];
|
|
5575
|
+
for (const name of ["ITPAY_HUB_URL", "ITPAY_HUB_OAUTH_ISSUER", "ITPAY_HUB_OAUTH_CLIENT", "ITPAY_HUB_OAUTH_SCOPE", "ITPAY_STATE_DIR"]) {
|
|
5576
|
+
const raw = process.env[name];
|
|
5577
|
+
if (!raw) continue;
|
|
5578
|
+
if (name === "ITPAY_HUB_URL" || name === "ITPAY_HUB_OAUTH_ISSUER") {
|
|
5579
|
+
try {
|
|
5580
|
+
const u = new URL(raw);
|
|
5581
|
+
if (!["http:", "https:"].includes(u.protocol) || u.username || u.password || u.search || u.hash) return null;
|
|
5582
|
+
} catch {
|
|
5583
|
+
return null;
|
|
5584
|
+
}
|
|
5585
|
+
}
|
|
5586
|
+
const quoted = "'" + raw.replaceAll("'", `'"'"'`) + "'";
|
|
5587
|
+
assignments.push(name + "=" + quoted);
|
|
5588
|
+
}
|
|
5589
|
+
return { ...action, command: [...assignments, qualifyItPayCommand(action.command, declaredAgentType())].join(" ") };
|
|
5590
|
+
}, "qualify");
|
|
5591
|
+
value = { ...value, next: value.next ? qualify(value.next) : null, recovery: value.recovery.map(qualify).filter((action) => action !== null) };
|
|
5571
5592
|
const out = options.output ?? ((text2) => {
|
|
5572
5593
|
process.stdout.write(text2);
|
|
5573
5594
|
});
|
|
@@ -5650,7 +5671,9 @@ async function runHubInspect(operationID2, options) {
|
|
|
5650
5671
|
input_schema: desc.input_schema ?? null
|
|
5651
5672
|
},
|
|
5652
5673
|
instruction: desc.status !== "published" ? "\u8BE5\u64CD\u4F5C\u5F53\u524D\u4E0D\u53EF\u8FD0\u884C\uFF1B\u4E0D\u8981\u53D1\u8D77 run\u3002" : "\u4F7F\u7528 current_publication_id \u7ED1\u5B9A\u8FD0\u884C\uFF1B\u5E26 effect_class=external_write/purchase \u7684\u64CD\u4F5C\u9700\u8981\u7528\u6237\u786E\u8BA4\u3002",
|
|
5653
|
-
|
|
5674
|
+
// Actual user input is still required; help is executable without calling
|
|
5675
|
+
// the supplier, while a placeholder is not a runnable action.
|
|
5676
|
+
next: desc.status === "published" ? { command: "itpay api run --help", reason: "\u6309 input_schema \u548C\u7528\u6237\u9700\u6C42\u51C6\u5907\u771F\u5B9E\u8F93\u5165\uFF1B\u6B64\u5E2E\u52A9\u547D\u4EE4\u4E0D\u6267\u884C API" } : null,
|
|
5654
5677
|
recovery: []
|
|
5655
5678
|
}, {
|
|
5656
5679
|
jsonOutput: Boolean(options.jsonOutput),
|
|
@@ -5746,42 +5769,68 @@ async function runHubRun(operationID2, options) {
|
|
|
5746
5769
|
throw new Error(`idempotency_conflict: request ${task.request_id} already exists with different input/publication/credential selection \u2014 use a new --request-id or "itpay api resume ${task.request_id}"`);
|
|
5747
5770
|
}
|
|
5748
5771
|
if (!created && task.run_id) {
|
|
5749
|
-
const
|
|
5750
|
-
store.update(task.request_id, { status:
|
|
5751
|
-
renderRun(
|
|
5772
|
+
const rec = await waitForRun(client, task.run_id, options.waitSeconds ?? 0);
|
|
5773
|
+
store.update(task.request_id, { status: rec.execution_state === "succeeded" ? "succeeded" : rec.execution_state === "failed" ? "failed" : "dispatched" });
|
|
5774
|
+
renderRun(rec, options.jsonOutput, "replayed");
|
|
5752
5775
|
return;
|
|
5753
5776
|
}
|
|
5754
5777
|
if (!created && task.intent_id) {
|
|
5755
5778
|
await renderBlockedTask(task, null, options.jsonOutput);
|
|
5756
5779
|
return;
|
|
5757
5780
|
}
|
|
5758
|
-
|
|
5759
|
-
|
|
5760
|
-
|
|
5761
|
-
|
|
5762
|
-
|
|
5763
|
-
|
|
5764
|
-
if (options.maxCharge) {
|
|
5765
|
-
body.max_charge = { currency: "CNY", scale: 6, amount_atoms: options.maxCharge };
|
|
5766
|
-
}
|
|
5767
|
-
store.update(task.request_id, { status: "dispatched" });
|
|
5768
|
-
const admission = await client.run(operationID2, body, store.idempotencyKey(task.request_id));
|
|
5769
|
-
if (!isRunReceipt(admission)) {
|
|
5770
|
-
store.update(task.request_id, { status: "blocked", intent_id: admission.intent_id, blocking_reason: admission.blocking_reason });
|
|
5771
|
-
await renderBlockedTask(task, admission, options.jsonOutput);
|
|
5772
|
-
return;
|
|
5781
|
+
await dispatchOriginalTask(client, store, task, options);
|
|
5782
|
+
}
|
|
5783
|
+
__name(runHubRun, "runHubRun");
|
|
5784
|
+
var HubTaskRequestError = class extends Error {
|
|
5785
|
+
static {
|
|
5786
|
+
__name(this, "HubTaskRequestError");
|
|
5773
5787
|
}
|
|
5774
|
-
|
|
5775
|
-
|
|
5776
|
-
|
|
5777
|
-
|
|
5788
|
+
requestID;
|
|
5789
|
+
references;
|
|
5790
|
+
code;
|
|
5791
|
+
constructor(error, task) {
|
|
5792
|
+
super(error instanceof Error ? error.message : "original Hub request did not return a receipt");
|
|
5793
|
+
this.requestID = task.request_id;
|
|
5794
|
+
this.references = { request_id: task.request_id, ...task.run_id ? { run_id: task.run_id } : {}, ...task.intent_id ? { intent_id: task.intent_id } : {} };
|
|
5795
|
+
this.code = error instanceof HttpError ? error.code : ["authorization_required", "idempotency_conflict", "invalid_state"].find((code) => this.message.startsWith(code + ":")) ?? "hub_request_unknown";
|
|
5796
|
+
}
|
|
5797
|
+
};
|
|
5798
|
+
async function dispatchOriginalTask(client, store, task, options) {
|
|
5799
|
+
try {
|
|
5800
|
+
const selections = { ...task.credential_id ? { credential_id: task.credential_id } : {}, ...task.source_credentials ? { source_credentials: task.source_credentials } : {} };
|
|
5801
|
+
if (task.input_digest !== digestTask(task.operation_id, task.publication_id, task.input, task.max_charge_atoms, selections)) {
|
|
5802
|
+
throw new Error("idempotency_conflict: stored request facts do not match the original digest; preserve this task for review");
|
|
5803
|
+
}
|
|
5804
|
+
const body = {
|
|
5805
|
+
expected_publication_id: task.publication_id,
|
|
5806
|
+
input: task.input,
|
|
5807
|
+
...task.credential_id ? { credential_id: task.credential_id } : {},
|
|
5808
|
+
...task.source_credentials ? { source_credentials: task.source_credentials } : {}
|
|
5809
|
+
};
|
|
5810
|
+
if (task.max_charge_atoms) {
|
|
5811
|
+
body.max_charge = { currency: "CNY", scale: 6, amount_atoms: task.max_charge_atoms };
|
|
5812
|
+
}
|
|
5813
|
+
store.update(task.request_id, { status: "dispatched" });
|
|
5814
|
+
const admission = await client.run(task.operation_id, body, store.idempotencyKey(task.request_id));
|
|
5815
|
+
if (!isRunReceipt(admission)) {
|
|
5816
|
+
store.update(task.request_id, { status: "blocked", intent_id: admission.intent_id, blocking_reason: admission.blocking_reason });
|
|
5817
|
+
await renderBlockedTask(task, admission, options.jsonOutput);
|
|
5818
|
+
return;
|
|
5819
|
+
}
|
|
5820
|
+
let rec = admission;
|
|
5821
|
+
store.update(task.request_id, { run_id: rec.run_id });
|
|
5822
|
+
if (options.waitSeconds) {
|
|
5823
|
+
rec = await waitForRun(client, rec.run_id, options.waitSeconds);
|
|
5824
|
+
}
|
|
5825
|
+
store.update(task.request_id, {
|
|
5826
|
+
status: rec.execution_state === "succeeded" ? "succeeded" : rec.execution_state === "failed" ? "failed" : "dispatched"
|
|
5827
|
+
});
|
|
5828
|
+
renderRun(rec, options.jsonOutput);
|
|
5829
|
+
} catch (error) {
|
|
5830
|
+
throw new HubTaskRequestError(error, store.get(task.request_id) ?? task);
|
|
5778
5831
|
}
|
|
5779
|
-
store.update(task.request_id, {
|
|
5780
|
-
status: rec.execution_state === "succeeded" ? "succeeded" : rec.execution_state === "failed" ? "failed" : "dispatched"
|
|
5781
|
-
});
|
|
5782
|
-
renderRun(rec, options.jsonOutput);
|
|
5783
5832
|
}
|
|
5784
|
-
__name(
|
|
5833
|
+
__name(dispatchOriginalTask, "dispatchOriginalTask");
|
|
5785
5834
|
function renderRun(rec, jsonOutput, note) {
|
|
5786
5835
|
const charged = rec.actual_charge ? atomsToYuan(rec.actual_charge.amount_atoms) : "\xA50.000000";
|
|
5787
5836
|
writeCommandEnvelope({
|
|
@@ -6013,25 +6062,33 @@ async function runHubResume(requestID, options) {
|
|
|
6013
6062
|
if (!task) {
|
|
6014
6063
|
throw new Error(`not_found: unknown task ${requestID} \u2014 check "itpay api tasks"`);
|
|
6015
6064
|
}
|
|
6016
|
-
|
|
6017
|
-
|
|
6018
|
-
|
|
6019
|
-
|
|
6020
|
-
|
|
6021
|
-
|
|
6022
|
-
if (task.intent_id) {
|
|
6023
|
-
const res = await client.continueIntent(task.intent_id, `cli-continue-${requestID}`);
|
|
6024
|
-
if (res.run) {
|
|
6025
|
-
store.update(requestID, { run_id: res.run.run_id, status: res.run.execution_state === "succeeded" ? "succeeded" : "dispatched" });
|
|
6026
|
-
renderRun(res.run, options.jsonOutput);
|
|
6027
|
-
} else {
|
|
6028
|
-
const state = res.blocking_reason ?? res.state ?? res.status ?? "blocked";
|
|
6029
|
-
store.update(requestID, { blocking_reason: state });
|
|
6030
|
-
await renderBlockedTask(task, { ...res, intent_id: task.intent_id, blocking_reason: state }, options.jsonOutput);
|
|
6065
|
+
try {
|
|
6066
|
+
if (task.run_id) {
|
|
6067
|
+
const rec = await waitForRun(client, task.run_id, options.waitSeconds ?? 0);
|
|
6068
|
+
store.update(requestID, { status: rec.execution_state === "succeeded" ? "succeeded" : rec.execution_state === "failed" ? "failed" : "dispatched" });
|
|
6069
|
+
renderRun(rec, options.jsonOutput);
|
|
6070
|
+
return;
|
|
6031
6071
|
}
|
|
6032
|
-
|
|
6072
|
+
if (task.intent_id) {
|
|
6073
|
+
const res = await client.continueIntent(task.intent_id, `cli-continue-${requestID}`);
|
|
6074
|
+
if (res.run) {
|
|
6075
|
+
store.update(requestID, { run_id: res.run.run_id, status: res.run.execution_state === "succeeded" ? "succeeded" : "dispatched" });
|
|
6076
|
+
renderRun(res.run, options.jsonOutput);
|
|
6077
|
+
} else {
|
|
6078
|
+
const state = res.blocking_reason ?? res.state ?? res.status ?? "blocked";
|
|
6079
|
+
store.update(requestID, { blocking_reason: state });
|
|
6080
|
+
await renderBlockedTask(task, { ...res, intent_id: task.intent_id, blocking_reason: state }, options.jsonOutput);
|
|
6081
|
+
}
|
|
6082
|
+
return;
|
|
6083
|
+
}
|
|
6084
|
+
if (!["pending", "dispatched", "unknown"].includes(task.status)) {
|
|
6085
|
+
throw new HubTaskRequestError(new Error("invalid_state: original task has no authoritative run or intent; preserve it for review"), task);
|
|
6086
|
+
}
|
|
6087
|
+
await dispatchOriginalTask(client, store, task, options);
|
|
6088
|
+
} catch (error) {
|
|
6089
|
+
if (error instanceof HubTaskRequestError) throw error;
|
|
6090
|
+
throw new HubTaskRequestError(error, store.get(requestID) ?? task);
|
|
6033
6091
|
}
|
|
6034
|
-
throw new Error(`invalid_state: task ${requestID} has no run or intent \u2014 it never reached the server`);
|
|
6035
6092
|
}
|
|
6036
6093
|
__name(runHubResume, "runHubResume");
|
|
6037
6094
|
async function runHubTasks(options) {
|
|
@@ -6134,7 +6191,12 @@ __name(runHubConnect, "runHubConnect");
|
|
|
6134
6191
|
|
|
6135
6192
|
// src/commands/api_commands.ts
|
|
6136
6193
|
function reportCLIError(error, contract) {
|
|
6137
|
-
|
|
6194
|
+
const code = error instanceof HubTaskRequestError ? error.code : error instanceof HttpError ? error.code : error instanceof Error && error.message.startsWith("authorization_required:") ? "authorization_required" : contract?.code ?? "command_failed";
|
|
6195
|
+
const auth = code === "authorization_required" || code === "unauthenticated";
|
|
6196
|
+
const taskID = error instanceof HubTaskRequestError ? error.requestID : void 0;
|
|
6197
|
+
const references = error instanceof HubTaskRequestError ? error.references : void 0;
|
|
6198
|
+
const recover = taskID ? { command: qualifyItPayCommand(references?.run_id ? `itpay api run-status ${references.run_id}${contract?.jsonOutput ? " --json" : ""}` : `itpay api resume ${taskID}${contract?.jsonOutput ? " --json" : ""}`, declaredAgentType()), reason: "\u8BFB\u53D6\u6216\u6062\u590D\u540C\u4E00\u539F\u4EFB\u52A1\uFF0C\u4E0D\u521B\u5EFA\u66FF\u4EE3\u8BF7\u6C42" } : null;
|
|
6199
|
+
writeCommandEnvelope({ status: "error", error: { code, message: error instanceof Error ? error.message : String(error) }, ...references ? { result: references } : {}, instruction: auth ? "\u5148\u5B8C\u6210 ItPay API \u6B63\u5E38\u8FDE\u63A5\uFF1B\u4FDD\u7559\u539F\u8EAB\u4EFD\u548C\u4EFB\u52A1\uFF0C\u4E0D\u8981\u521B\u5EFA\u66FF\u4EE3\u8BF7\u6C42\u3002" : ["idempotency_conflict", "invalid_state"].includes(code) ? "\u539F\u4EFB\u52A1\u8BB0\u5F55\u4E0D\u4E00\u81F4\uFF1B\u4FDD\u7559\u8BB0\u5F55\u6838\u5BF9\uFF0C\u4E0D\u80FD\u4FEE\u6539\u51BB\u7ED3\u53C2\u6570\u7EE7\u7EED\u53D1\u9001\u3002" : taskID ? "\u539F\u8BF7\u6C42\u5C1A\u672A\u53D6\u5F97\u53EF\u7528\u56DE\u6267\uFF1B\u8FD9\u4E0D\u4EE3\u8868\u672A\u5230\u8FBE\u670D\u52A1\u5668\u3002\u4FDD\u7559\u539F\u8BF7\u6C42\u6062\u590D\uFF0C\u4E0D\u91CD\u65B0\u8C03\u7528\u6216\u5145\u503C\u3002" : contract?.instruction ?? "Check the command and current Hub connection; preserve original tasks.", next: auth ? { command: qualifyItPayCommand(`itpay api connect${contract?.jsonOutput ? " --json" : ""}`, declaredAgentType()), reason: "\u6B63\u5E38\u6388\u6743\u540E\u7EE7\u7EED\u539F\u4EFB\u52A1" } : ["idempotency_conflict", "invalid_state", "forbidden", "publication_changed", "credential_revalidation_required"].includes(code) ? null : recover, recovery: auth && recover ? [recover] : contract?.recovery ?? [] }, { jsonOutput: contract?.jsonOutput ?? process.argv.includes("--json") });
|
|
6138
6200
|
process.exitCode = 1;
|
|
6139
6201
|
}
|
|
6140
6202
|
__name(reportCLIError, "reportCLIError");
|
|
@@ -12880,7 +12942,7 @@ function railInvocationProjection(response, requestedCapability, input, itemCoun
|
|
|
12880
12942
|
__name(railInvocationProjection, "railInvocationProjection");
|
|
12881
12943
|
|
|
12882
12944
|
// src/services/rail/recovery.ts
|
|
12883
|
-
var RAIL_LOCATION_EVIDENCE_REASONS = /* @__PURE__ */ new Set(["endpoint_kind_conflict", "place_identity_uncertain", "endpoint_adcode_name_conflict", "endpoint_poi_name_conflict", "endpoint_station_name_code_conflict", "location_evidence_required", "coordinate_name_mismatch", "area_scope_too_broad", "address_required", "administrative_area_unresolved", "station_location_evidence_required", "coordinate_identity_unverified"]);
|
|
12945
|
+
var RAIL_LOCATION_EVIDENCE_REASONS = /* @__PURE__ */ new Set(["station_jurisdiction_evidence_required", "endpoint_kind_conflict", "place_identity_uncertain", "endpoint_adcode_name_conflict", "endpoint_poi_name_conflict", "endpoint_station_name_code_conflict", "location_evidence_required", "coordinate_name_mismatch", "area_scope_too_broad", "address_required", "administrative_area_unresolved", "station_location_evidence_required", "coordinate_identity_unverified"]);
|
|
12884
12946
|
var RAIL_QUOTE_FAILURE_GUIDANCE = {
|
|
12885
12947
|
quote_source_unavailable: "\u5B9E\u65F6\u8F66\u7968\u6570\u636E\u6682\u4E0D\u53EF\u7528\uFF1B\u4FDD\u7559\u539F\u9009\u62E9\uFF0C\u7A0D\u540E\u6309\u7528\u6237\u610F\u613F\u91CD\u65B0\u6838\u9A8C\uFF0C\u4E0D\u521B\u5EFA\u66FF\u4EE3\u8BA2\u5355\u3002",
|
|
12886
12948
|
quote_train_changed: "\u6240\u9009\u8F66\u6B21\u7684\u65F6\u523B\u6216\u8FD0\u884C\u4FE1\u606F\u5DF2\u53D8\u5316\uFF1B\u5411\u7528\u6237\u8BF4\u660E\u5E76\u5F81\u8BE2\u662F\u5426\u91CD\u65B0\u67E5\u7968\u3002",
|
|
@@ -13000,6 +13062,9 @@ function railWorkflowEnvelope(model) {
|
|
|
13000
13062
|
const affected = model.workflow?.failure?.endpoint ?? model.workflow?.dependency?.endpoint;
|
|
13001
13063
|
const query = model.workflow?.query_input ?? {};
|
|
13002
13064
|
const endpoints = query.endpoints && typeof query.endpoints === "object" ? query.endpoints : {};
|
|
13065
|
+
if (code === "station_jurisdiction_evidence_required") {
|
|
13066
|
+
return { status: "system_evidence_required", result: { service_execution_id: id, reason: code, failed_step: model.workflow?.failure?.step_id, failure: model.workflow?.failure, query, ...affected === "origin" || affected === "destination" ? { affected_endpoint: affected, original_place: endpoints[affected]?.text ?? query[affected] } : {} }, instruction: "\u5730\u56FE\u5730\u70B9\u672A\u80FD\u56DE\u5339\u539F\u94C1\u8DEF\u7AD9\u8EAB\u4EFD\uFF0C\u9700\u670D\u52A1\u7EF4\u62A4\u65B9\u6838\u5BF9\u5730\u56FE\u4E0E\u94C1\u8DEF\u76EE\u5F55\u4E8B\u5B9E\u3002\u4FDD\u7559\u5B8C\u6574\u539F\u9700\u6C42\u53CA\u5DF2\u89E3\u6790\u53E6\u4E00\u7AEF\uFF1B\u4E0D\u8981\u6C42\u7528\u6237\u6539\u5730\u5740\uFF0C\u4E0D\u6362kind\u3001\u7AD9\u3001\u65E5\u671F\u6216\u731C\u5750\u6807\u3002\u5F53\u524D\u65E0\u53EF\u6267\u884C\u6062\u590D\uFF0C\u505C\u6B62\uFF1B\u4E0D\u91CD\u65B0\u67E5\u7968\u6216\u521B\u5EFA\u8D2D\u4E70\u3002", next: null, recovery: [] };
|
|
13067
|
+
}
|
|
13003
13068
|
const stationPair = [endpoints.origin, endpoints.destination].every((endpoint) => endpoint?.kind === "station" && typeof endpoint.text === "string" && endpoint.text.trim() && typeof endpoint.station_code === "string" && /^[A-Z]{3}$/.test(endpoint.station_code));
|
|
13004
13069
|
if (code === "station_location_evidence_required") {
|
|
13005
13070
|
const exactInput = stationPair && typeof query.travel_date === "string" ? { origin: endpoints.origin.text, destination: endpoints.destination.text, travel_date: query.travel_date } : void 0;
|
|
@@ -16639,7 +16704,7 @@ import { createHash as createHash12 } from "node:crypto";
|
|
|
16639
16704
|
|
|
16640
16705
|
// src/state/skill_identity.generated.ts
|
|
16641
16706
|
var CANONICAL_SKILL_SHA256 = "dcbce8347f9ed4a95b89bbd680bbfb2c5308f1081e1af1554f413b950eb902dc";
|
|
16642
|
-
var CANONICAL_API_SKILL_SHA256 = "
|
|
16707
|
+
var CANONICAL_API_SKILL_SHA256 = "70af9cc2363b1c60174e4159e296b64c183c833a20930e8612c265bb69c238e6";
|
|
16643
16708
|
|
|
16644
16709
|
// src/commands/skill.ts
|
|
16645
16710
|
import { existsSync as existsSync9, readFileSync as readFileSync16 } from "node:fs";
|
package/dist/src/state/config.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itpay/cli",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.61",
|
|
4
4
|
"description": "The ItPay CLI for services, orders, and human-authorized purchased content.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -148,5 +148,5 @@
|
|
|
148
148
|
"services",
|
|
149
149
|
"api"
|
|
150
150
|
],
|
|
151
|
-
"gitHead": "
|
|
151
|
+
"gitHead": "928231fd3c11229cd9116a36fcbf3ff1eef6402f"
|
|
152
152
|
}
|
|
@@ -11,6 +11,8 @@ For a new task, prefer the official pinned ItPay CLI when execution is permitted
|
|
|
11
11
|
|
|
12
12
|
Use this Skill for API tasks; Services/railway instructions are not prerequisites. Use the installed pinned launcher and `itpay api --help`; `hub` is its compatibility alias. Keep the actual host/Agent Type, ITPAY_HUB_URL and permitted ITPAY_STATE_DIR across every command/session. Never switch accounts, spoof a host or clear identity to recover quota.
|
|
13
13
|
|
|
14
|
+
For an explicitly authorized **v4 dev API** task, select `ITPAY_HUB_URL=https://market-v4-dev.itpay.ai` before the first API command and preserve it with the permitted state directory. Its OAuth issuer is `https://auth-v4-dev.itpay.ai`; the CLI selects that issuer for this exact dev Hub unless explicitly configured otherwise. CLI resource is the Hub root, not the hosted MCP `/mcp` URL. For example, after the user selects v4 dev: `ITPAY_HUB_URL=https://market-v4-dev.itpay.ai itpay api connect --json`. Never select or switch dev merely because a request failed, and never infer the API identity from Services configuration. Local defaults and other explicit Hub/issuer configurations remain separate.
|
|
15
|
+
|
|
14
16
|
Connect with the existing `itpay api connect` browser OAuth flow when authentication is required. The human enters verification privately. Existing credentials and task files belong to their endpoint/resource; sharing an ItPay account does not merge OAuth grants, API budgets, Services devices or data ACLs. Never request tokens or codes in chat. Use `api doctor` only for an actual connection problem, not before every task.
|
|
15
17
|
|
|
16
18
|
Discover the published operation, inspect its current publication, input schema, effects, price and limits, then choose it only if it expresses all user constraints. Read normal text/JSON directly; do not write a parser or infer operation IDs from names. Read the exact command's help as needed. Templates containing placeholders are not executable next actions.
|