@t2000/cli 10.0.0 → 10.1.0

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.
@@ -33171,7 +33171,7 @@ function camelToSnakeCaseObject(obj) {
33171
33171
  return result;
33172
33172
  }
33173
33173
  var init_utils6 = __esm({
33174
- "../../node_modules/.pnpm/@pythnetwork+hermes-client@3.1.0_axios@1.15.2/node_modules/@pythnetwork/hermes-client/dist/esm/utils.mjs"() {
33174
+ "../../node_modules/.pnpm/@pythnetwork+hermes-client@3.1.0_axios@1.16.1/node_modules/@pythnetwork/hermes-client/dist/esm/utils.mjs"() {
33175
33175
  }
33176
33176
  });
33177
33177
  function bind(fn, thisArg) {
@@ -33180,7 +33180,7 @@ function bind(fn, thisArg) {
33180
33180
  };
33181
33181
  }
33182
33182
  var init_bind = __esm({
33183
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/bind.js"() {
33183
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/bind.js"() {
33184
33184
  }
33185
33185
  });
33186
33186
  function isBuffer(val) {
@@ -33244,7 +33244,7 @@ function findKey(obj, key) {
33244
33244
  }
33245
33245
  return null;
33246
33246
  }
33247
- function merge2() {
33247
+ function merge2(...objs) {
33248
33248
  const { caseless, skipUndefined } = isContextDefined(this) && this || {};
33249
33249
  const result = {};
33250
33250
  const assignValue = (val, key) => {
@@ -33252,8 +33252,9 @@ function merge2() {
33252
33252
  return;
33253
33253
  }
33254
33254
  const targetKey = caseless && findKey(result, key) || key;
33255
- if (isPlainObject3(result[targetKey]) && isPlainObject3(val)) {
33256
- result[targetKey] = merge2(result[targetKey], val);
33255
+ const existing = hasOwnProperty(result, targetKey) ? result[targetKey] : void 0;
33256
+ if (isPlainObject3(existing) && isPlainObject3(val)) {
33257
+ result[targetKey] = merge2(existing, val);
33257
33258
  } else if (isPlainObject3(val)) {
33258
33259
  result[targetKey] = merge2({}, val);
33259
33260
  } else if (isArray(val)) {
@@ -33262,8 +33263,8 @@ function merge2() {
33262
33263
  result[targetKey] = val;
33263
33264
  }
33264
33265
  };
33265
- for (let i = 0, l2 = arguments.length; i < l2; i++) {
33266
- arguments[i] && forEach(arguments[i], assignValue);
33266
+ for (let i = 0, l2 = objs.length; i < l2; i++) {
33267
+ objs[i] && forEach(objs[i], assignValue);
33267
33268
  }
33268
33269
  return result;
33269
33270
  }
@@ -33331,7 +33332,7 @@ var asap;
33331
33332
  var isIterable;
33332
33333
  var utils_default;
33333
33334
  var init_utils7 = __esm({
33334
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/utils.js"() {
33335
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/utils.js"() {
33335
33336
  init_bind();
33336
33337
  ({ toString } = Object.prototype);
33337
33338
  ({ getPrototypeOf } = Object);
@@ -33412,6 +33413,9 @@ var init_utils7 = __esm({
33412
33413
  (val, key) => {
33413
33414
  if (thisArg && isFunction(val)) {
33414
33415
  Object.defineProperty(a, key, {
33416
+ // Null-proto descriptor so a polluted Object.prototype.get cannot
33417
+ // hijack defineProperty's accessor-vs-data resolution.
33418
+ __proto__: null,
33415
33419
  value: bind(val, thisArg),
33416
33420
  writable: true,
33417
33421
  enumerable: true,
@@ -33419,6 +33423,7 @@ var init_utils7 = __esm({
33419
33423
  });
33420
33424
  } else {
33421
33425
  Object.defineProperty(a, key, {
33426
+ __proto__: null,
33422
33427
  value: val,
33423
33428
  writable: true,
33424
33429
  enumerable: true,
@@ -33439,12 +33444,14 @@ var init_utils7 = __esm({
33439
33444
  inherits = (constructor, superConstructor, props, descriptors) => {
33440
33445
  constructor.prototype = Object.create(superConstructor.prototype, descriptors);
33441
33446
  Object.defineProperty(constructor.prototype, "constructor", {
33447
+ __proto__: null,
33442
33448
  value: constructor,
33443
33449
  writable: true,
33444
33450
  enumerable: false,
33445
33451
  configurable: true
33446
33452
  });
33447
33453
  Object.defineProperty(constructor, "super", {
33454
+ __proto__: null,
33448
33455
  value: superConstructor.prototype
33449
33456
  });
33450
33457
  props && Object.assign(constructor.prototype, props);
@@ -33533,7 +33540,7 @@ var init_utils7 = __esm({
33533
33540
  };
33534
33541
  freezeMethods = (obj) => {
33535
33542
  reduceDescriptors(obj, (descriptor, name) => {
33536
- if (isFunction(obj) && ["arguments", "caller", "callee"].indexOf(name) !== -1) {
33543
+ if (isFunction(obj) && ["arguments", "caller", "callee"].includes(name)) {
33537
33544
  return false;
33538
33545
  }
33539
33546
  const value = obj[name];
@@ -33566,29 +33573,29 @@ var init_utils7 = __esm({
33566
33573
  return value != null && Number.isFinite(value = +value) ? value : defaultValue;
33567
33574
  };
33568
33575
  toJSONObject = (obj) => {
33569
- const stack = new Array(10);
33570
- const visit2 = (source, i) => {
33576
+ const visited = /* @__PURE__ */ new WeakSet();
33577
+ const visit2 = (source) => {
33571
33578
  if (isObject2(source)) {
33572
- if (stack.indexOf(source) >= 0) {
33579
+ if (visited.has(source)) {
33573
33580
  return;
33574
33581
  }
33575
33582
  if (isBuffer(source)) {
33576
33583
  return source;
33577
33584
  }
33578
33585
  if (!("toJSON" in source)) {
33579
- stack[i] = source;
33586
+ visited.add(source);
33580
33587
  const target = isArray(source) ? [] : {};
33581
33588
  forEach(source, (value, key) => {
33582
- const reducedValue = visit2(value, i + 1);
33589
+ const reducedValue = visit2(value);
33583
33590
  !isUndefined(reducedValue) && (target[key] = reducedValue);
33584
33591
  });
33585
- stack[i] = void 0;
33592
+ visited.delete(source);
33586
33593
  return target;
33587
33594
  }
33588
33595
  }
33589
33596
  return source;
33590
33597
  };
33591
- return visit2(obj, 0);
33598
+ return visit2(obj);
33592
33599
  };
33593
33600
  isAsyncFn = kindOfTest("AsyncFunction");
33594
33601
  isThenable = (thing) => thing && (isObject2(thing) || isFunction(thing)) && isFunction(thing.then) && isFunction(thing.catch);
@@ -33678,11 +33685,408 @@ var init_utils7 = __esm({
33678
33685
  };
33679
33686
  }
33680
33687
  });
33688
+ var ignoreDuplicateOf;
33689
+ var parseHeaders_default;
33690
+ var init_parseHeaders = __esm({
33691
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/parseHeaders.js"() {
33692
+ init_utils7();
33693
+ ignoreDuplicateOf = utils_default.toObjectSet([
33694
+ "age",
33695
+ "authorization",
33696
+ "content-length",
33697
+ "content-type",
33698
+ "etag",
33699
+ "expires",
33700
+ "from",
33701
+ "host",
33702
+ "if-modified-since",
33703
+ "if-unmodified-since",
33704
+ "last-modified",
33705
+ "location",
33706
+ "max-forwards",
33707
+ "proxy-authorization",
33708
+ "referer",
33709
+ "retry-after",
33710
+ "user-agent"
33711
+ ]);
33712
+ parseHeaders_default = (rawHeaders) => {
33713
+ const parsed = {};
33714
+ let key;
33715
+ let val;
33716
+ let i;
33717
+ rawHeaders && rawHeaders.split("\n").forEach(function parser(line) {
33718
+ i = line.indexOf(":");
33719
+ key = line.substring(0, i).trim().toLowerCase();
33720
+ val = line.substring(i + 1).trim();
33721
+ if (!key || parsed[key] && ignoreDuplicateOf[key]) {
33722
+ return;
33723
+ }
33724
+ if (key === "set-cookie") {
33725
+ if (parsed[key]) {
33726
+ parsed[key].push(val);
33727
+ } else {
33728
+ parsed[key] = [val];
33729
+ }
33730
+ } else {
33731
+ parsed[key] = parsed[key] ? parsed[key] + ", " + val : val;
33732
+ }
33733
+ });
33734
+ return parsed;
33735
+ };
33736
+ }
33737
+ });
33738
+ function trimSPorHTAB(str) {
33739
+ let start = 0;
33740
+ let end = str.length;
33741
+ while (start < end) {
33742
+ const code = str.charCodeAt(start);
33743
+ if (code !== 9 && code !== 32) {
33744
+ break;
33745
+ }
33746
+ start += 1;
33747
+ }
33748
+ while (end > start) {
33749
+ const code = str.charCodeAt(end - 1);
33750
+ if (code !== 9 && code !== 32) {
33751
+ break;
33752
+ }
33753
+ end -= 1;
33754
+ }
33755
+ return start === 0 && end === str.length ? str : str.slice(start, end);
33756
+ }
33757
+ function sanitizeValue(value, invalidChars) {
33758
+ if (utils_default.isArray(value)) {
33759
+ return value.map((item) => sanitizeValue(item, invalidChars));
33760
+ }
33761
+ return trimSPorHTAB(String(value).replace(invalidChars, ""));
33762
+ }
33763
+ function toByteStringHeaderObject(headers) {
33764
+ const byteStringHeaders = /* @__PURE__ */ Object.create(null);
33765
+ utils_default.forEach(headers.toJSON(), (value, header) => {
33766
+ byteStringHeaders[header] = sanitizeByteStringHeaderValue(value);
33767
+ });
33768
+ return byteStringHeaders;
33769
+ }
33770
+ var INVALID_UNICODE_HEADER_VALUE_CHARS;
33771
+ var INVALID_BYTE_STRING_HEADER_VALUE_CHARS;
33772
+ var sanitizeHeaderValue;
33773
+ var sanitizeByteStringHeaderValue;
33774
+ var init_sanitizeHeaderValue = __esm({
33775
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/sanitizeHeaderValue.js"() {
33776
+ init_utils7();
33777
+ INVALID_UNICODE_HEADER_VALUE_CHARS = new RegExp("[\\u0000-\\u0008\\u000a-\\u001f\\u007f]+", "g");
33778
+ INVALID_BYTE_STRING_HEADER_VALUE_CHARS = new RegExp("[^\\u0009\\u0020-\\u007e\\u0080-\\u00ff]+", "g");
33779
+ sanitizeHeaderValue = (value) => sanitizeValue(value, INVALID_UNICODE_HEADER_VALUE_CHARS);
33780
+ sanitizeByteStringHeaderValue = (value) => sanitizeValue(value, INVALID_BYTE_STRING_HEADER_VALUE_CHARS);
33781
+ }
33782
+ });
33783
+ function normalizeHeader(header) {
33784
+ return header && String(header).trim().toLowerCase();
33785
+ }
33786
+ function normalizeValue(value) {
33787
+ if (value === false || value == null) {
33788
+ return value;
33789
+ }
33790
+ return utils_default.isArray(value) ? value.map(normalizeValue) : sanitizeHeaderValue(String(value));
33791
+ }
33792
+ function parseTokens(str) {
33793
+ const tokens2 = /* @__PURE__ */ Object.create(null);
33794
+ const tokensRE = /([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;
33795
+ let match;
33796
+ while (match = tokensRE.exec(str)) {
33797
+ tokens2[match[1]] = match[2];
33798
+ }
33799
+ return tokens2;
33800
+ }
33801
+ function matchHeaderValue(context, value, header, filter2, isHeaderNameFilter) {
33802
+ if (utils_default.isFunction(filter2)) {
33803
+ return filter2.call(this, value, header);
33804
+ }
33805
+ if (isHeaderNameFilter) {
33806
+ value = header;
33807
+ }
33808
+ if (!utils_default.isString(value)) return;
33809
+ if (utils_default.isString(filter2)) {
33810
+ return value.indexOf(filter2) !== -1;
33811
+ }
33812
+ if (utils_default.isRegExp(filter2)) {
33813
+ return filter2.test(value);
33814
+ }
33815
+ }
33816
+ function formatHeader(header) {
33817
+ return header.trim().toLowerCase().replace(/([a-z\d])(\w*)/g, (w2, char, str) => {
33818
+ return char.toUpperCase() + str;
33819
+ });
33820
+ }
33821
+ function buildAccessors(obj, header) {
33822
+ const accessorName = utils_default.toCamelCase(" " + header);
33823
+ ["get", "set", "has"].forEach((methodName) => {
33824
+ Object.defineProperty(obj, methodName + accessorName, {
33825
+ // Null-proto descriptor so a polluted Object.prototype.get cannot turn
33826
+ // this data descriptor into an accessor descriptor on the way in.
33827
+ __proto__: null,
33828
+ value: function(arg1, arg2, arg3) {
33829
+ return this[methodName].call(this, header, arg1, arg2, arg3);
33830
+ },
33831
+ configurable: true
33832
+ });
33833
+ });
33834
+ }
33835
+ var $internals;
33836
+ var isValidHeaderName;
33837
+ var AxiosHeaders;
33838
+ var AxiosHeaders_default;
33839
+ var init_AxiosHeaders = __esm({
33840
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/core/AxiosHeaders.js"() {
33841
+ init_utils7();
33842
+ init_parseHeaders();
33843
+ init_sanitizeHeaderValue();
33844
+ $internals = /* @__PURE__ */ Symbol("internals");
33845
+ isValidHeaderName = (str) => /^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(str.trim());
33846
+ AxiosHeaders = class {
33847
+ constructor(headers) {
33848
+ headers && this.set(headers);
33849
+ }
33850
+ set(header, valueOrRewrite, rewrite) {
33851
+ const self2 = this;
33852
+ function setHeader(_value, _header, _rewrite) {
33853
+ const lHeader = normalizeHeader(_header);
33854
+ if (!lHeader) {
33855
+ throw new Error("header name must be a non-empty string");
33856
+ }
33857
+ const key = utils_default.findKey(self2, lHeader);
33858
+ if (!key || self2[key] === void 0 || _rewrite === true || _rewrite === void 0 && self2[key] !== false) {
33859
+ self2[key || _header] = normalizeValue(_value);
33860
+ }
33861
+ }
33862
+ const setHeaders = (headers, _rewrite) => utils_default.forEach(headers, (_value, _header) => setHeader(_value, _header, _rewrite));
33863
+ if (utils_default.isPlainObject(header) || header instanceof this.constructor) {
33864
+ setHeaders(header, valueOrRewrite);
33865
+ } else if (utils_default.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {
33866
+ setHeaders(parseHeaders_default(header), valueOrRewrite);
33867
+ } else if (utils_default.isObject(header) && utils_default.isIterable(header)) {
33868
+ let obj = {}, dest, key;
33869
+ for (const entry of header) {
33870
+ if (!utils_default.isArray(entry)) {
33871
+ throw TypeError("Object iterator must return a key-value pair");
33872
+ }
33873
+ obj[key = entry[0]] = (dest = obj[key]) ? utils_default.isArray(dest) ? [...dest, entry[1]] : [dest, entry[1]] : entry[1];
33874
+ }
33875
+ setHeaders(obj, valueOrRewrite);
33876
+ } else {
33877
+ header != null && setHeader(valueOrRewrite, header, rewrite);
33878
+ }
33879
+ return this;
33880
+ }
33881
+ get(header, parser) {
33882
+ header = normalizeHeader(header);
33883
+ if (header) {
33884
+ const key = utils_default.findKey(this, header);
33885
+ if (key) {
33886
+ const value = this[key];
33887
+ if (!parser) {
33888
+ return value;
33889
+ }
33890
+ if (parser === true) {
33891
+ return parseTokens(value);
33892
+ }
33893
+ if (utils_default.isFunction(parser)) {
33894
+ return parser.call(this, value, key);
33895
+ }
33896
+ if (utils_default.isRegExp(parser)) {
33897
+ return parser.exec(value);
33898
+ }
33899
+ throw new TypeError("parser must be boolean|regexp|function");
33900
+ }
33901
+ }
33902
+ }
33903
+ has(header, matcher) {
33904
+ header = normalizeHeader(header);
33905
+ if (header) {
33906
+ const key = utils_default.findKey(this, header);
33907
+ return !!(key && this[key] !== void 0 && (!matcher || matchHeaderValue(this, this[key], key, matcher)));
33908
+ }
33909
+ return false;
33910
+ }
33911
+ delete(header, matcher) {
33912
+ const self2 = this;
33913
+ let deleted = false;
33914
+ function deleteHeader(_header) {
33915
+ _header = normalizeHeader(_header);
33916
+ if (_header) {
33917
+ const key = utils_default.findKey(self2, _header);
33918
+ if (key && (!matcher || matchHeaderValue(self2, self2[key], key, matcher))) {
33919
+ delete self2[key];
33920
+ deleted = true;
33921
+ }
33922
+ }
33923
+ }
33924
+ if (utils_default.isArray(header)) {
33925
+ header.forEach(deleteHeader);
33926
+ } else {
33927
+ deleteHeader(header);
33928
+ }
33929
+ return deleted;
33930
+ }
33931
+ clear(matcher) {
33932
+ const keys = Object.keys(this);
33933
+ let i = keys.length;
33934
+ let deleted = false;
33935
+ while (i--) {
33936
+ const key = keys[i];
33937
+ if (!matcher || matchHeaderValue(this, this[key], key, matcher, true)) {
33938
+ delete this[key];
33939
+ deleted = true;
33940
+ }
33941
+ }
33942
+ return deleted;
33943
+ }
33944
+ normalize(format3) {
33945
+ const self2 = this;
33946
+ const headers = {};
33947
+ utils_default.forEach(this, (value, header) => {
33948
+ const key = utils_default.findKey(headers, header);
33949
+ if (key) {
33950
+ self2[key] = normalizeValue(value);
33951
+ delete self2[header];
33952
+ return;
33953
+ }
33954
+ const normalized = format3 ? formatHeader(header) : String(header).trim();
33955
+ if (normalized !== header) {
33956
+ delete self2[header];
33957
+ }
33958
+ self2[normalized] = normalizeValue(value);
33959
+ headers[normalized] = true;
33960
+ });
33961
+ return this;
33962
+ }
33963
+ concat(...targets) {
33964
+ return this.constructor.concat(this, ...targets);
33965
+ }
33966
+ toJSON(asStrings) {
33967
+ const obj = /* @__PURE__ */ Object.create(null);
33968
+ utils_default.forEach(this, (value, header) => {
33969
+ value != null && value !== false && (obj[header] = asStrings && utils_default.isArray(value) ? value.join(", ") : value);
33970
+ });
33971
+ return obj;
33972
+ }
33973
+ [Symbol.iterator]() {
33974
+ return Object.entries(this.toJSON())[Symbol.iterator]();
33975
+ }
33976
+ toString() {
33977
+ return Object.entries(this.toJSON()).map(([header, value]) => header + ": " + value).join("\n");
33978
+ }
33979
+ getSetCookie() {
33980
+ return this.get("set-cookie") || [];
33981
+ }
33982
+ get [Symbol.toStringTag]() {
33983
+ return "AxiosHeaders";
33984
+ }
33985
+ static from(thing) {
33986
+ return thing instanceof this ? thing : new this(thing);
33987
+ }
33988
+ static concat(first, ...targets) {
33989
+ const computed = new this(first);
33990
+ targets.forEach((target) => computed.set(target));
33991
+ return computed;
33992
+ }
33993
+ static accessor(header) {
33994
+ const internals = this[$internals] = this[$internals] = {
33995
+ accessors: {}
33996
+ };
33997
+ const accessors = internals.accessors;
33998
+ const prototype2 = this.prototype;
33999
+ function defineAccessor(_header) {
34000
+ const lHeader = normalizeHeader(_header);
34001
+ if (!accessors[lHeader]) {
34002
+ buildAccessors(prototype2, _header);
34003
+ accessors[lHeader] = true;
34004
+ }
34005
+ }
34006
+ utils_default.isArray(header) ? header.forEach(defineAccessor) : defineAccessor(header);
34007
+ return this;
34008
+ }
34009
+ };
34010
+ AxiosHeaders.accessor([
34011
+ "Content-Type",
34012
+ "Content-Length",
34013
+ "Accept",
34014
+ "Accept-Encoding",
34015
+ "User-Agent",
34016
+ "Authorization"
34017
+ ]);
34018
+ utils_default.reduceDescriptors(AxiosHeaders.prototype, ({ value }, key) => {
34019
+ let mapped = key[0].toUpperCase() + key.slice(1);
34020
+ return {
34021
+ get: () => value,
34022
+ set(headerValue) {
34023
+ this[mapped] = headerValue;
34024
+ }
34025
+ };
34026
+ });
34027
+ utils_default.freezeMethods(AxiosHeaders);
34028
+ AxiosHeaders_default = AxiosHeaders;
34029
+ }
34030
+ });
34031
+ function hasOwnOrPrototypeToJSON(source) {
34032
+ if (utils_default.hasOwnProp(source, "toJSON")) {
34033
+ return true;
34034
+ }
34035
+ let prototype2 = Object.getPrototypeOf(source);
34036
+ while (prototype2 && prototype2 !== Object.prototype) {
34037
+ if (utils_default.hasOwnProp(prototype2, "toJSON")) {
34038
+ return true;
34039
+ }
34040
+ prototype2 = Object.getPrototypeOf(prototype2);
34041
+ }
34042
+ return false;
34043
+ }
34044
+ function redactConfig(config4, redactKeys) {
34045
+ const lowerKeys = new Set(redactKeys.map((k) => String(k).toLowerCase()));
34046
+ const seen = [];
34047
+ const visit2 = (source) => {
34048
+ if (source === null || typeof source !== "object") return source;
34049
+ if (utils_default.isBuffer(source)) return source;
34050
+ if (seen.indexOf(source) !== -1) return void 0;
34051
+ if (source instanceof AxiosHeaders_default) {
34052
+ source = source.toJSON();
34053
+ }
34054
+ seen.push(source);
34055
+ let result;
34056
+ if (utils_default.isArray(source)) {
34057
+ result = [];
34058
+ source.forEach((v, i) => {
34059
+ const reducedValue = visit2(v);
34060
+ if (!utils_default.isUndefined(reducedValue)) {
34061
+ result[i] = reducedValue;
34062
+ }
34063
+ });
34064
+ } else {
34065
+ if (!utils_default.isPlainObject(source) && hasOwnOrPrototypeToJSON(source)) {
34066
+ seen.pop();
34067
+ return source;
34068
+ }
34069
+ result = /* @__PURE__ */ Object.create(null);
34070
+ for (const [key, value] of Object.entries(source)) {
34071
+ const reducedValue = lowerKeys.has(key.toLowerCase()) ? REDACTED : visit2(value);
34072
+ if (!utils_default.isUndefined(reducedValue)) {
34073
+ result[key] = reducedValue;
34074
+ }
34075
+ }
34076
+ }
34077
+ seen.pop();
34078
+ return result;
34079
+ };
34080
+ return visit2(config4);
34081
+ }
34082
+ var REDACTED;
33681
34083
  var AxiosError;
33682
34084
  var AxiosError_default;
33683
34085
  var init_AxiosError = __esm({
33684
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/core/AxiosError.js"() {
34086
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/core/AxiosError.js"() {
33685
34087
  init_utils7();
34088
+ init_AxiosHeaders();
34089
+ REDACTED = "[REDACTED ****]";
33686
34090
  AxiosError = class _AxiosError extends Error {
33687
34091
  static from(error52, code, config4, request, response, customProps) {
33688
34092
  const axiosError = new _AxiosError(error52.message, code || error52.code, config4, request, response);
@@ -33708,6 +34112,9 @@ var init_AxiosError = __esm({
33708
34112
  constructor(message, code, config4, request, response) {
33709
34113
  super(message);
33710
34114
  Object.defineProperty(this, "message", {
34115
+ // Null-proto descriptor so a polluted Object.prototype.get cannot turn
34116
+ // this data descriptor into an accessor descriptor on the way in.
34117
+ __proto__: null,
33711
34118
  value: message,
33712
34119
  enumerable: true,
33713
34120
  writable: true,
@@ -33724,6 +34131,9 @@ var init_AxiosError = __esm({
33724
34131
  }
33725
34132
  }
33726
34133
  toJSON() {
34134
+ const config4 = this.config;
34135
+ const redactKeys = config4 && utils_default.hasOwnProp(config4, "redact") ? config4.redact : void 0;
34136
+ const serializedConfig = utils_default.isArray(redactKeys) && redactKeys.length > 0 ? redactConfig(config4, redactKeys) : utils_default.toJSONObject(config4);
33727
34137
  return {
33728
34138
  // Standard
33729
34139
  message: this.message,
@@ -33737,7 +34147,7 @@ var init_AxiosError = __esm({
33737
34147
  columnNumber: this.columnNumber,
33738
34148
  stack: this.stack,
33739
34149
  // Axios
33740
- config: utils_default.toJSONObject(this.config),
34150
+ config: serializedConfig,
33741
34151
  code: this.code,
33742
34152
  status: this.status
33743
34153
  };
@@ -33747,6 +34157,7 @@ var init_AxiosError = __esm({
33747
34157
  AxiosError.ERR_BAD_OPTION = "ERR_BAD_OPTION";
33748
34158
  AxiosError.ECONNABORTED = "ECONNABORTED";
33749
34159
  AxiosError.ETIMEDOUT = "ETIMEDOUT";
34160
+ AxiosError.ECONNREFUSED = "ECONNREFUSED";
33750
34161
  AxiosError.ERR_NETWORK = "ERR_NETWORK";
33751
34162
  AxiosError.ERR_FR_TOO_MANY_REDIRECTS = "ERR_FR_TOO_MANY_REDIRECTS";
33752
34163
  AxiosError.ERR_DEPRECATED = "ERR_DEPRECATED";
@@ -43886,7 +44297,7 @@ var require_form_data = __commonJS({
43886
44297
  var import_form_data;
43887
44298
  var FormData_default;
43888
44299
  var init_FormData = __esm({
43889
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/platform/node/classes/FormData.js"() {
44300
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/platform/node/classes/FormData.js"() {
43890
44301
  import_form_data = __toESM(require_form_data());
43891
44302
  FormData_default = import_form_data.default;
43892
44303
  }
@@ -44013,7 +44424,7 @@ function toFormData(obj, formData, options) {
44013
44424
  var predicates;
44014
44425
  var toFormData_default;
44015
44426
  var init_toFormData = __esm({
44016
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/toFormData.js"() {
44427
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/toFormData.js"() {
44017
44428
  init_utils7();
44018
44429
  init_AxiosError();
44019
44430
  init_FormData();
@@ -44043,7 +44454,7 @@ function AxiosURLSearchParams(params, options) {
44043
44454
  var prototype;
44044
44455
  var AxiosURLSearchParams_default;
44045
44456
  var init_AxiosURLSearchParams = __esm({
44046
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/AxiosURLSearchParams.js"() {
44457
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/AxiosURLSearchParams.js"() {
44047
44458
  init_toFormData();
44048
44459
  prototype = AxiosURLSearchParams.prototype;
44049
44460
  prototype.append = function append(name, value) {
@@ -44088,7 +44499,7 @@ function buildURL(url3, params, options) {
44088
44499
  return url3;
44089
44500
  }
44090
44501
  var init_buildURL = __esm({
44091
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/buildURL.js"() {
44502
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/buildURL.js"() {
44092
44503
  init_utils7();
44093
44504
  init_AxiosURLSearchParams();
44094
44505
  }
@@ -44096,7 +44507,7 @@ var init_buildURL = __esm({
44096
44507
  var InterceptorManager;
44097
44508
  var InterceptorManager_default;
44098
44509
  var init_InterceptorManager = __esm({
44099
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/core/InterceptorManager.js"() {
44510
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/core/InterceptorManager.js"() {
44100
44511
  init_utils7();
44101
44512
  InterceptorManager = class {
44102
44513
  constructor() {
@@ -44165,7 +44576,7 @@ var init_InterceptorManager = __esm({
44165
44576
  });
44166
44577
  var transitional_default;
44167
44578
  var init_transitional = __esm({
44168
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/defaults/transitional.js"() {
44579
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/defaults/transitional.js"() {
44169
44580
  transitional_default = {
44170
44581
  silentJSONParsing: true,
44171
44582
  forcedJSONParsing: true,
@@ -44176,7 +44587,7 @@ var init_transitional = __esm({
44176
44587
  });
44177
44588
  var URLSearchParams_default;
44178
44589
  var init_URLSearchParams = __esm({
44179
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/platform/node/classes/URLSearchParams.js"() {
44590
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/platform/node/classes/URLSearchParams.js"() {
44180
44591
  URLSearchParams_default = Url.URLSearchParams;
44181
44592
  }
44182
44593
  });
@@ -44186,7 +44597,7 @@ var ALPHABET;
44186
44597
  var generateString;
44187
44598
  var node_default;
44188
44599
  var init_node = __esm({
44189
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/platform/node/index.js"() {
44600
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/platform/node/index.js"() {
44190
44601
  init_URLSearchParams();
44191
44602
  init_FormData();
44192
44603
  ALPHA = "abcdefghijklmnopqrstuvwxyz";
@@ -44233,7 +44644,7 @@ var hasStandardBrowserEnv;
44233
44644
  var hasStandardBrowserWebWorkerEnv;
44234
44645
  var origin;
44235
44646
  var init_utils8 = __esm({
44236
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/platform/common/utils.js"() {
44647
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/platform/common/utils.js"() {
44237
44648
  hasBrowserEnv = typeof window !== "undefined" && typeof document !== "undefined";
44238
44649
  _navigator = typeof navigator === "object" && navigator || void 0;
44239
44650
  hasStandardBrowserEnv = hasBrowserEnv && (!_navigator || ["ReactNative", "NativeScript", "NS"].indexOf(_navigator.product) < 0);
@@ -44246,7 +44657,7 @@ var init_utils8 = __esm({
44246
44657
  });
44247
44658
  var platform_default;
44248
44659
  var init_platform = __esm({
44249
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/platform/index.js"() {
44660
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/platform/index.js"() {
44250
44661
  init_node();
44251
44662
  init_utils8();
44252
44663
  platform_default = {
@@ -44268,7 +44679,7 @@ function toURLEncodedForm(data, options) {
44268
44679
  });
44269
44680
  }
44270
44681
  var init_toURLEncodedForm = __esm({
44271
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/toURLEncodedForm.js"() {
44682
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/toURLEncodedForm.js"() {
44272
44683
  init_utils7();
44273
44684
  init_toFormData();
44274
44685
  init_platform();
@@ -44306,7 +44717,7 @@ function formDataToJSON(formData) {
44306
44717
  }
44307
44718
  return !isNumericKey;
44308
44719
  }
44309
- if (!target[name] || !utils_default.isObject(target[name])) {
44720
+ if (!utils_default.hasOwnProp(target, name) || !utils_default.isObject(target[name])) {
44310
44721
  target[name] = [];
44311
44722
  }
44312
44723
  const result = buildPath(path, value, target[name], index2);
@@ -44326,7 +44737,7 @@ function formDataToJSON(formData) {
44326
44737
  }
44327
44738
  var formDataToJSON_default;
44328
44739
  var init_formDataToJSON = __esm({
44329
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/formDataToJSON.js"() {
44740
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/formDataToJSON.js"() {
44330
44741
  init_utils7();
44331
44742
  formDataToJSON_default = formDataToJSON;
44332
44743
  }
@@ -44348,7 +44759,7 @@ var own;
44348
44759
  var defaults;
44349
44760
  var defaults_default;
44350
44761
  var init_defaults = __esm({
44351
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/defaults/index.js"() {
44762
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/defaults/index.js"() {
44352
44763
  init_utils7();
44353
44764
  init_AxiosError();
44354
44765
  init_transitional();
@@ -44454,330 +44865,12 @@ var init_defaults = __esm({
44454
44865
  }
44455
44866
  }
44456
44867
  };
44457
- utils_default.forEach(["delete", "get", "head", "post", "put", "patch"], (method) => {
44868
+ utils_default.forEach(["delete", "get", "head", "post", "put", "patch", "query"], (method) => {
44458
44869
  defaults.headers[method] = {};
44459
44870
  });
44460
44871
  defaults_default = defaults;
44461
44872
  }
44462
44873
  });
44463
- var ignoreDuplicateOf;
44464
- var parseHeaders_default;
44465
- var init_parseHeaders = __esm({
44466
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/parseHeaders.js"() {
44467
- init_utils7();
44468
- ignoreDuplicateOf = utils_default.toObjectSet([
44469
- "age",
44470
- "authorization",
44471
- "content-length",
44472
- "content-type",
44473
- "etag",
44474
- "expires",
44475
- "from",
44476
- "host",
44477
- "if-modified-since",
44478
- "if-unmodified-since",
44479
- "last-modified",
44480
- "location",
44481
- "max-forwards",
44482
- "proxy-authorization",
44483
- "referer",
44484
- "retry-after",
44485
- "user-agent"
44486
- ]);
44487
- parseHeaders_default = (rawHeaders) => {
44488
- const parsed = {};
44489
- let key;
44490
- let val;
44491
- let i;
44492
- rawHeaders && rawHeaders.split("\n").forEach(function parser(line) {
44493
- i = line.indexOf(":");
44494
- key = line.substring(0, i).trim().toLowerCase();
44495
- val = line.substring(i + 1).trim();
44496
- if (!key || parsed[key] && ignoreDuplicateOf[key]) {
44497
- return;
44498
- }
44499
- if (key === "set-cookie") {
44500
- if (parsed[key]) {
44501
- parsed[key].push(val);
44502
- } else {
44503
- parsed[key] = [val];
44504
- }
44505
- } else {
44506
- parsed[key] = parsed[key] ? parsed[key] + ", " + val : val;
44507
- }
44508
- });
44509
- return parsed;
44510
- };
44511
- }
44512
- });
44513
- function trimSPorHTAB(str) {
44514
- let start = 0;
44515
- let end = str.length;
44516
- while (start < end) {
44517
- const code = str.charCodeAt(start);
44518
- if (code !== 9 && code !== 32) {
44519
- break;
44520
- }
44521
- start += 1;
44522
- }
44523
- while (end > start) {
44524
- const code = str.charCodeAt(end - 1);
44525
- if (code !== 9 && code !== 32) {
44526
- break;
44527
- }
44528
- end -= 1;
44529
- }
44530
- return start === 0 && end === str.length ? str : str.slice(start, end);
44531
- }
44532
- function normalizeHeader(header) {
44533
- return header && String(header).trim().toLowerCase();
44534
- }
44535
- function sanitizeHeaderValue(str) {
44536
- return trimSPorHTAB(str.replace(INVALID_HEADER_VALUE_CHARS_RE, ""));
44537
- }
44538
- function normalizeValue(value) {
44539
- if (value === false || value == null) {
44540
- return value;
44541
- }
44542
- return utils_default.isArray(value) ? value.map(normalizeValue) : sanitizeHeaderValue(String(value));
44543
- }
44544
- function parseTokens(str) {
44545
- const tokens2 = /* @__PURE__ */ Object.create(null);
44546
- const tokensRE = /([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;
44547
- let match;
44548
- while (match = tokensRE.exec(str)) {
44549
- tokens2[match[1]] = match[2];
44550
- }
44551
- return tokens2;
44552
- }
44553
- function matchHeaderValue(context, value, header, filter2, isHeaderNameFilter) {
44554
- if (utils_default.isFunction(filter2)) {
44555
- return filter2.call(this, value, header);
44556
- }
44557
- if (isHeaderNameFilter) {
44558
- value = header;
44559
- }
44560
- if (!utils_default.isString(value)) return;
44561
- if (utils_default.isString(filter2)) {
44562
- return value.indexOf(filter2) !== -1;
44563
- }
44564
- if (utils_default.isRegExp(filter2)) {
44565
- return filter2.test(value);
44566
- }
44567
- }
44568
- function formatHeader(header) {
44569
- return header.trim().toLowerCase().replace(/([a-z\d])(\w*)/g, (w2, char, str) => {
44570
- return char.toUpperCase() + str;
44571
- });
44572
- }
44573
- function buildAccessors(obj, header) {
44574
- const accessorName = utils_default.toCamelCase(" " + header);
44575
- ["get", "set", "has"].forEach((methodName) => {
44576
- Object.defineProperty(obj, methodName + accessorName, {
44577
- value: function(arg1, arg2, arg3) {
44578
- return this[methodName].call(this, header, arg1, arg2, arg3);
44579
- },
44580
- configurable: true
44581
- });
44582
- });
44583
- }
44584
- var $internals;
44585
- var INVALID_HEADER_VALUE_CHARS_RE;
44586
- var isValidHeaderName;
44587
- var AxiosHeaders;
44588
- var AxiosHeaders_default;
44589
- var init_AxiosHeaders = __esm({
44590
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/core/AxiosHeaders.js"() {
44591
- init_utils7();
44592
- init_parseHeaders();
44593
- $internals = /* @__PURE__ */ Symbol("internals");
44594
- INVALID_HEADER_VALUE_CHARS_RE = /[^\x09\x20-\x7E\x80-\xFF]/g;
44595
- isValidHeaderName = (str) => /^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(str.trim());
44596
- AxiosHeaders = class {
44597
- constructor(headers) {
44598
- headers && this.set(headers);
44599
- }
44600
- set(header, valueOrRewrite, rewrite) {
44601
- const self2 = this;
44602
- function setHeader(_value, _header, _rewrite) {
44603
- const lHeader = normalizeHeader(_header);
44604
- if (!lHeader) {
44605
- throw new Error("header name must be a non-empty string");
44606
- }
44607
- const key = utils_default.findKey(self2, lHeader);
44608
- if (!key || self2[key] === void 0 || _rewrite === true || _rewrite === void 0 && self2[key] !== false) {
44609
- self2[key || _header] = normalizeValue(_value);
44610
- }
44611
- }
44612
- const setHeaders = (headers, _rewrite) => utils_default.forEach(headers, (_value, _header) => setHeader(_value, _header, _rewrite));
44613
- if (utils_default.isPlainObject(header) || header instanceof this.constructor) {
44614
- setHeaders(header, valueOrRewrite);
44615
- } else if (utils_default.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {
44616
- setHeaders(parseHeaders_default(header), valueOrRewrite);
44617
- } else if (utils_default.isObject(header) && utils_default.isIterable(header)) {
44618
- let obj = {}, dest, key;
44619
- for (const entry of header) {
44620
- if (!utils_default.isArray(entry)) {
44621
- throw TypeError("Object iterator must return a key-value pair");
44622
- }
44623
- obj[key = entry[0]] = (dest = obj[key]) ? utils_default.isArray(dest) ? [...dest, entry[1]] : [dest, entry[1]] : entry[1];
44624
- }
44625
- setHeaders(obj, valueOrRewrite);
44626
- } else {
44627
- header != null && setHeader(valueOrRewrite, header, rewrite);
44628
- }
44629
- return this;
44630
- }
44631
- get(header, parser) {
44632
- header = normalizeHeader(header);
44633
- if (header) {
44634
- const key = utils_default.findKey(this, header);
44635
- if (key) {
44636
- const value = this[key];
44637
- if (!parser) {
44638
- return value;
44639
- }
44640
- if (parser === true) {
44641
- return parseTokens(value);
44642
- }
44643
- if (utils_default.isFunction(parser)) {
44644
- return parser.call(this, value, key);
44645
- }
44646
- if (utils_default.isRegExp(parser)) {
44647
- return parser.exec(value);
44648
- }
44649
- throw new TypeError("parser must be boolean|regexp|function");
44650
- }
44651
- }
44652
- }
44653
- has(header, matcher) {
44654
- header = normalizeHeader(header);
44655
- if (header) {
44656
- const key = utils_default.findKey(this, header);
44657
- return !!(key && this[key] !== void 0 && (!matcher || matchHeaderValue(this, this[key], key, matcher)));
44658
- }
44659
- return false;
44660
- }
44661
- delete(header, matcher) {
44662
- const self2 = this;
44663
- let deleted = false;
44664
- function deleteHeader(_header) {
44665
- _header = normalizeHeader(_header);
44666
- if (_header) {
44667
- const key = utils_default.findKey(self2, _header);
44668
- if (key && (!matcher || matchHeaderValue(self2, self2[key], key, matcher))) {
44669
- delete self2[key];
44670
- deleted = true;
44671
- }
44672
- }
44673
- }
44674
- if (utils_default.isArray(header)) {
44675
- header.forEach(deleteHeader);
44676
- } else {
44677
- deleteHeader(header);
44678
- }
44679
- return deleted;
44680
- }
44681
- clear(matcher) {
44682
- const keys = Object.keys(this);
44683
- let i = keys.length;
44684
- let deleted = false;
44685
- while (i--) {
44686
- const key = keys[i];
44687
- if (!matcher || matchHeaderValue(this, this[key], key, matcher, true)) {
44688
- delete this[key];
44689
- deleted = true;
44690
- }
44691
- }
44692
- return deleted;
44693
- }
44694
- normalize(format3) {
44695
- const self2 = this;
44696
- const headers = {};
44697
- utils_default.forEach(this, (value, header) => {
44698
- const key = utils_default.findKey(headers, header);
44699
- if (key) {
44700
- self2[key] = normalizeValue(value);
44701
- delete self2[header];
44702
- return;
44703
- }
44704
- const normalized = format3 ? formatHeader(header) : String(header).trim();
44705
- if (normalized !== header) {
44706
- delete self2[header];
44707
- }
44708
- self2[normalized] = normalizeValue(value);
44709
- headers[normalized] = true;
44710
- });
44711
- return this;
44712
- }
44713
- concat(...targets) {
44714
- return this.constructor.concat(this, ...targets);
44715
- }
44716
- toJSON(asStrings) {
44717
- const obj = /* @__PURE__ */ Object.create(null);
44718
- utils_default.forEach(this, (value, header) => {
44719
- value != null && value !== false && (obj[header] = asStrings && utils_default.isArray(value) ? value.join(", ") : value);
44720
- });
44721
- return obj;
44722
- }
44723
- [Symbol.iterator]() {
44724
- return Object.entries(this.toJSON())[Symbol.iterator]();
44725
- }
44726
- toString() {
44727
- return Object.entries(this.toJSON()).map(([header, value]) => header + ": " + value).join("\n");
44728
- }
44729
- getSetCookie() {
44730
- return this.get("set-cookie") || [];
44731
- }
44732
- get [Symbol.toStringTag]() {
44733
- return "AxiosHeaders";
44734
- }
44735
- static from(thing) {
44736
- return thing instanceof this ? thing : new this(thing);
44737
- }
44738
- static concat(first, ...targets) {
44739
- const computed = new this(first);
44740
- targets.forEach((target) => computed.set(target));
44741
- return computed;
44742
- }
44743
- static accessor(header) {
44744
- const internals = this[$internals] = this[$internals] = {
44745
- accessors: {}
44746
- };
44747
- const accessors = internals.accessors;
44748
- const prototype2 = this.prototype;
44749
- function defineAccessor(_header) {
44750
- const lHeader = normalizeHeader(_header);
44751
- if (!accessors[lHeader]) {
44752
- buildAccessors(prototype2, _header);
44753
- accessors[lHeader] = true;
44754
- }
44755
- }
44756
- utils_default.isArray(header) ? header.forEach(defineAccessor) : defineAccessor(header);
44757
- return this;
44758
- }
44759
- };
44760
- AxiosHeaders.accessor([
44761
- "Content-Type",
44762
- "Content-Length",
44763
- "Accept",
44764
- "Accept-Encoding",
44765
- "User-Agent",
44766
- "Authorization"
44767
- ]);
44768
- utils_default.reduceDescriptors(AxiosHeaders.prototype, ({ value }, key) => {
44769
- let mapped = key[0].toUpperCase() + key.slice(1);
44770
- return {
44771
- get: () => value,
44772
- set(headerValue) {
44773
- this[mapped] = headerValue;
44774
- }
44775
- };
44776
- });
44777
- utils_default.freezeMethods(AxiosHeaders);
44778
- AxiosHeaders_default = AxiosHeaders;
44779
- }
44780
- });
44781
44874
  function transformData(fns, response) {
44782
44875
  const config4 = this || defaults_default;
44783
44876
  const context = response || config4;
@@ -44790,7 +44883,7 @@ function transformData(fns, response) {
44790
44883
  return data;
44791
44884
  }
44792
44885
  var init_transformData = __esm({
44793
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/core/transformData.js"() {
44886
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/core/transformData.js"() {
44794
44887
  init_utils7();
44795
44888
  init_defaults();
44796
44889
  init_AxiosHeaders();
@@ -44800,13 +44893,13 @@ function isCancel(value) {
44800
44893
  return !!(value && value.__CANCEL__);
44801
44894
  }
44802
44895
  var init_isCancel = __esm({
44803
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/cancel/isCancel.js"() {
44896
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/cancel/isCancel.js"() {
44804
44897
  }
44805
44898
  });
44806
44899
  var CanceledError;
44807
44900
  var CanceledError_default;
44808
44901
  var init_CanceledError = __esm({
44809
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/cancel/CanceledError.js"() {
44902
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/cancel/CanceledError.js"() {
44810
44903
  init_AxiosError();
44811
44904
  CanceledError = class extends AxiosError_default {
44812
44905
  /**
@@ -44832,19 +44925,17 @@ function settle(resolve4, reject, response) {
44832
44925
  if (!response.status || !validateStatus2 || validateStatus2(response.status)) {
44833
44926
  resolve4(response);
44834
44927
  } else {
44835
- reject(
44836
- new AxiosError_default(
44837
- "Request failed with status code " + response.status,
44838
- [AxiosError_default.ERR_BAD_REQUEST, AxiosError_default.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4],
44839
- response.config,
44840
- response.request,
44841
- response
44842
- )
44843
- );
44928
+ reject(new AxiosError_default(
44929
+ "Request failed with status code " + response.status,
44930
+ response.status >= 400 && response.status < 500 ? AxiosError_default.ERR_BAD_REQUEST : AxiosError_default.ERR_BAD_RESPONSE,
44931
+ response.config,
44932
+ response.request,
44933
+ response
44934
+ ));
44844
44935
  }
44845
44936
  }
44846
44937
  var init_settle = __esm({
44847
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/core/settle.js"() {
44938
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/core/settle.js"() {
44848
44939
  init_AxiosError();
44849
44940
  }
44850
44941
  });
@@ -44855,14 +44946,14 @@ function isAbsoluteURL(url3) {
44855
44946
  return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url3);
44856
44947
  }
44857
44948
  var init_isAbsoluteURL = __esm({
44858
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/isAbsoluteURL.js"() {
44949
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/isAbsoluteURL.js"() {
44859
44950
  }
44860
44951
  });
44861
44952
  function combineURLs(baseURL, relativeURL) {
44862
44953
  return relativeURL ? baseURL.replace(/\/?\/$/, "") + "/" + relativeURL.replace(/^\/+/, "") : baseURL;
44863
44954
  }
44864
44955
  var init_combineURLs = __esm({
44865
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/combineURLs.js"() {
44956
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/combineURLs.js"() {
44866
44957
  }
44867
44958
  });
44868
44959
  function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) {
@@ -44873,7 +44964,7 @@ function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) {
44873
44964
  return requestedURL;
44874
44965
  }
44875
44966
  var init_buildFullPath = __esm({
44876
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/core/buildFullPath.js"() {
44967
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/core/buildFullPath.js"() {
44877
44968
  init_isAbsoluteURL();
44878
44969
  init_combineURLs();
44879
44970
  }
@@ -45695,8 +45786,443 @@ var require_src = __commonJS({
45695
45786
  }
45696
45787
  }
45697
45788
  });
45789
+ var require_promisify = __commonJS({
45790
+ "../../node_modules/.pnpm/agent-base@6.0.2/node_modules/agent-base/dist/src/promisify.js"(exports$1) {
45791
+ Object.defineProperty(exports$1, "__esModule", { value: true });
45792
+ function promisify(fn) {
45793
+ return function(req, opts) {
45794
+ return new Promise((resolve4, reject) => {
45795
+ fn.call(this, req, opts, (err, rtn) => {
45796
+ if (err) {
45797
+ reject(err);
45798
+ } else {
45799
+ resolve4(rtn);
45800
+ }
45801
+ });
45802
+ });
45803
+ };
45804
+ }
45805
+ exports$1.default = promisify;
45806
+ }
45807
+ });
45808
+ var require_src2 = __commonJS({
45809
+ "../../node_modules/.pnpm/agent-base@6.0.2/node_modules/agent-base/dist/src/index.js"(exports$1, module) {
45810
+ var __importDefault = exports$1 && exports$1.__importDefault || function(mod5) {
45811
+ return mod5 && mod5.__esModule ? mod5 : { "default": mod5 };
45812
+ };
45813
+ var events_1 = __require("events");
45814
+ var debug_1 = __importDefault(require_src());
45815
+ var promisify_1 = __importDefault(require_promisify());
45816
+ var debug = debug_1.default("agent-base");
45817
+ function isAgent(v) {
45818
+ return Boolean(v) && typeof v.addRequest === "function";
45819
+ }
45820
+ function isSecureEndpoint() {
45821
+ const { stack } = new Error();
45822
+ if (typeof stack !== "string")
45823
+ return false;
45824
+ return stack.split("\n").some((l2) => l2.indexOf("(https.js:") !== -1 || l2.indexOf("node:https:") !== -1);
45825
+ }
45826
+ function createAgent2(callback, opts) {
45827
+ return new createAgent2.Agent(callback, opts);
45828
+ }
45829
+ (function(createAgent3) {
45830
+ class Agent extends events_1.EventEmitter {
45831
+ constructor(callback, _opts) {
45832
+ super();
45833
+ let opts = _opts;
45834
+ if (typeof callback === "function") {
45835
+ this.callback = callback;
45836
+ } else if (callback) {
45837
+ opts = callback;
45838
+ }
45839
+ this.timeout = null;
45840
+ if (opts && typeof opts.timeout === "number") {
45841
+ this.timeout = opts.timeout;
45842
+ }
45843
+ this.maxFreeSockets = 1;
45844
+ this.maxSockets = 1;
45845
+ this.maxTotalSockets = Infinity;
45846
+ this.sockets = {};
45847
+ this.freeSockets = {};
45848
+ this.requests = {};
45849
+ this.options = {};
45850
+ }
45851
+ get defaultPort() {
45852
+ if (typeof this.explicitDefaultPort === "number") {
45853
+ return this.explicitDefaultPort;
45854
+ }
45855
+ return isSecureEndpoint() ? 443 : 80;
45856
+ }
45857
+ set defaultPort(v) {
45858
+ this.explicitDefaultPort = v;
45859
+ }
45860
+ get protocol() {
45861
+ if (typeof this.explicitProtocol === "string") {
45862
+ return this.explicitProtocol;
45863
+ }
45864
+ return isSecureEndpoint() ? "https:" : "http:";
45865
+ }
45866
+ set protocol(v) {
45867
+ this.explicitProtocol = v;
45868
+ }
45869
+ callback(req, opts, fn) {
45870
+ throw new Error('"agent-base" has no default implementation, you must subclass and override `callback()`');
45871
+ }
45872
+ /**
45873
+ * Called by node-core's "_http_client.js" module when creating
45874
+ * a new HTTP request with this Agent instance.
45875
+ *
45876
+ * @api public
45877
+ */
45878
+ addRequest(req, _opts) {
45879
+ const opts = Object.assign({}, _opts);
45880
+ if (typeof opts.secureEndpoint !== "boolean") {
45881
+ opts.secureEndpoint = isSecureEndpoint();
45882
+ }
45883
+ if (opts.host == null) {
45884
+ opts.host = "localhost";
45885
+ }
45886
+ if (opts.port == null) {
45887
+ opts.port = opts.secureEndpoint ? 443 : 80;
45888
+ }
45889
+ if (opts.protocol == null) {
45890
+ opts.protocol = opts.secureEndpoint ? "https:" : "http:";
45891
+ }
45892
+ if (opts.host && opts.path) {
45893
+ delete opts.path;
45894
+ }
45895
+ delete opts.agent;
45896
+ delete opts.hostname;
45897
+ delete opts._defaultAgent;
45898
+ delete opts.defaultPort;
45899
+ delete opts.createConnection;
45900
+ req._last = true;
45901
+ req.shouldKeepAlive = false;
45902
+ let timedOut = false;
45903
+ let timeoutId = null;
45904
+ const timeoutMs = opts.timeout || this.timeout;
45905
+ const onerror = (err) => {
45906
+ if (req._hadError)
45907
+ return;
45908
+ req.emit("error", err);
45909
+ req._hadError = true;
45910
+ };
45911
+ const ontimeout = () => {
45912
+ timeoutId = null;
45913
+ timedOut = true;
45914
+ const err = new Error(`A "socket" was not created for HTTP request before ${timeoutMs}ms`);
45915
+ err.code = "ETIMEOUT";
45916
+ onerror(err);
45917
+ };
45918
+ const callbackError = (err) => {
45919
+ if (timedOut)
45920
+ return;
45921
+ if (timeoutId !== null) {
45922
+ clearTimeout(timeoutId);
45923
+ timeoutId = null;
45924
+ }
45925
+ onerror(err);
45926
+ };
45927
+ const onsocket = (socket) => {
45928
+ if (timedOut)
45929
+ return;
45930
+ if (timeoutId != null) {
45931
+ clearTimeout(timeoutId);
45932
+ timeoutId = null;
45933
+ }
45934
+ if (isAgent(socket)) {
45935
+ debug("Callback returned another Agent instance %o", socket.constructor.name);
45936
+ socket.addRequest(req, opts);
45937
+ return;
45938
+ }
45939
+ if (socket) {
45940
+ socket.once("free", () => {
45941
+ this.freeSocket(socket, opts);
45942
+ });
45943
+ req.onSocket(socket);
45944
+ return;
45945
+ }
45946
+ const err = new Error(`no Duplex stream was returned to agent-base for \`${req.method} ${req.path}\``);
45947
+ onerror(err);
45948
+ };
45949
+ if (typeof this.callback !== "function") {
45950
+ onerror(new Error("`callback` is not defined"));
45951
+ return;
45952
+ }
45953
+ if (!this.promisifiedCallback) {
45954
+ if (this.callback.length >= 3) {
45955
+ debug("Converting legacy callback function to promise");
45956
+ this.promisifiedCallback = promisify_1.default(this.callback);
45957
+ } else {
45958
+ this.promisifiedCallback = this.callback;
45959
+ }
45960
+ }
45961
+ if (typeof timeoutMs === "number" && timeoutMs > 0) {
45962
+ timeoutId = setTimeout(ontimeout, timeoutMs);
45963
+ }
45964
+ if ("port" in opts && typeof opts.port !== "number") {
45965
+ opts.port = Number(opts.port);
45966
+ }
45967
+ try {
45968
+ debug("Resolving socket for %o request: %o", opts.protocol, `${req.method} ${req.path}`);
45969
+ Promise.resolve(this.promisifiedCallback(req, opts)).then(onsocket, callbackError);
45970
+ } catch (err) {
45971
+ Promise.reject(err).catch(callbackError);
45972
+ }
45973
+ }
45974
+ freeSocket(socket, opts) {
45975
+ debug("Freeing socket %o %o", socket.constructor.name, opts);
45976
+ socket.destroy();
45977
+ }
45978
+ destroy() {
45979
+ debug("Destroying agent %o", this.constructor.name);
45980
+ }
45981
+ }
45982
+ createAgent3.Agent = Agent;
45983
+ createAgent3.prototype = createAgent3.Agent.prototype;
45984
+ })(createAgent2 || (createAgent2 = {}));
45985
+ module.exports = createAgent2;
45986
+ }
45987
+ });
45988
+ var require_parse_proxy_response = __commonJS({
45989
+ "../../node_modules/.pnpm/https-proxy-agent@5.0.1/node_modules/https-proxy-agent/dist/parse-proxy-response.js"(exports$1) {
45990
+ var __importDefault = exports$1 && exports$1.__importDefault || function(mod5) {
45991
+ return mod5 && mod5.__esModule ? mod5 : { "default": mod5 };
45992
+ };
45993
+ Object.defineProperty(exports$1, "__esModule", { value: true });
45994
+ var debug_1 = __importDefault(require_src());
45995
+ var debug = debug_1.default("https-proxy-agent:parse-proxy-response");
45996
+ function parseProxyResponse(socket) {
45997
+ return new Promise((resolve4, reject) => {
45998
+ let buffersLength = 0;
45999
+ const buffers = [];
46000
+ function read() {
46001
+ const b = socket.read();
46002
+ if (b)
46003
+ ondata(b);
46004
+ else
46005
+ socket.once("readable", read);
46006
+ }
46007
+ function cleanup() {
46008
+ socket.removeListener("end", onend);
46009
+ socket.removeListener("error", onerror);
46010
+ socket.removeListener("close", onclose);
46011
+ socket.removeListener("readable", read);
46012
+ }
46013
+ function onclose(err) {
46014
+ debug("onclose had error %o", err);
46015
+ }
46016
+ function onend() {
46017
+ debug("onend");
46018
+ }
46019
+ function onerror(err) {
46020
+ cleanup();
46021
+ debug("onerror %o", err);
46022
+ reject(err);
46023
+ }
46024
+ function ondata(b) {
46025
+ buffers.push(b);
46026
+ buffersLength += b.length;
46027
+ const buffered = Buffer.concat(buffers, buffersLength);
46028
+ const endOfHeaders = buffered.indexOf("\r\n\r\n");
46029
+ if (endOfHeaders === -1) {
46030
+ debug("have not received end of HTTP headers yet...");
46031
+ read();
46032
+ return;
46033
+ }
46034
+ const firstLine = buffered.toString("ascii", 0, buffered.indexOf("\r\n"));
46035
+ const statusCode = +firstLine.split(" ")[1];
46036
+ debug("got proxy server response: %o", firstLine);
46037
+ resolve4({
46038
+ statusCode,
46039
+ buffered
46040
+ });
46041
+ }
46042
+ socket.on("error", onerror);
46043
+ socket.on("close", onclose);
46044
+ socket.on("end", onend);
46045
+ read();
46046
+ });
46047
+ }
46048
+ exports$1.default = parseProxyResponse;
46049
+ }
46050
+ });
46051
+ var require_agent = __commonJS({
46052
+ "../../node_modules/.pnpm/https-proxy-agent@5.0.1/node_modules/https-proxy-agent/dist/agent.js"(exports$1) {
46053
+ var __awaiter4 = exports$1 && exports$1.__awaiter || function(thisArg, _arguments, P3, generator) {
46054
+ function adopt(value) {
46055
+ return value instanceof P3 ? value : new P3(function(resolve4) {
46056
+ resolve4(value);
46057
+ });
46058
+ }
46059
+ return new (P3 || (P3 = Promise))(function(resolve4, reject) {
46060
+ function fulfilled(value) {
46061
+ try {
46062
+ step(generator.next(value));
46063
+ } catch (e) {
46064
+ reject(e);
46065
+ }
46066
+ }
46067
+ function rejected(value) {
46068
+ try {
46069
+ step(generator["throw"](value));
46070
+ } catch (e) {
46071
+ reject(e);
46072
+ }
46073
+ }
46074
+ function step(result) {
46075
+ result.done ? resolve4(result.value) : adopt(result.value).then(fulfilled, rejected);
46076
+ }
46077
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
46078
+ });
46079
+ };
46080
+ var __importDefault = exports$1 && exports$1.__importDefault || function(mod5) {
46081
+ return mod5 && mod5.__esModule ? mod5 : { "default": mod5 };
46082
+ };
46083
+ Object.defineProperty(exports$1, "__esModule", { value: true });
46084
+ var net_1 = __importDefault(__require("net"));
46085
+ var tls_1 = __importDefault(__require("tls"));
46086
+ var url_1 = __importDefault(__require("url"));
46087
+ var assert_1 = __importDefault(__require("assert"));
46088
+ var debug_1 = __importDefault(require_src());
46089
+ var agent_base_1 = require_src2();
46090
+ var parse_proxy_response_1 = __importDefault(require_parse_proxy_response());
46091
+ var debug = debug_1.default("https-proxy-agent:agent");
46092
+ var HttpsProxyAgent2 = class extends agent_base_1.Agent {
46093
+ constructor(_opts) {
46094
+ let opts;
46095
+ if (typeof _opts === "string") {
46096
+ opts = url_1.default.parse(_opts);
46097
+ } else {
46098
+ opts = _opts;
46099
+ }
46100
+ if (!opts) {
46101
+ throw new Error("an HTTP(S) proxy server `host` and `port` must be specified!");
46102
+ }
46103
+ debug("creating new HttpsProxyAgent instance: %o", opts);
46104
+ super(opts);
46105
+ const proxy = Object.assign({}, opts);
46106
+ this.secureProxy = opts.secureProxy || isHTTPS(proxy.protocol);
46107
+ proxy.host = proxy.hostname || proxy.host;
46108
+ if (typeof proxy.port === "string") {
46109
+ proxy.port = parseInt(proxy.port, 10);
46110
+ }
46111
+ if (!proxy.port && proxy.host) {
46112
+ proxy.port = this.secureProxy ? 443 : 80;
46113
+ }
46114
+ if (this.secureProxy && !("ALPNProtocols" in proxy)) {
46115
+ proxy.ALPNProtocols = ["http 1.1"];
46116
+ }
46117
+ if (proxy.host && proxy.path) {
46118
+ delete proxy.path;
46119
+ delete proxy.pathname;
46120
+ }
46121
+ this.proxy = proxy;
46122
+ }
46123
+ /**
46124
+ * Called when the node-core HTTP client library is creating a
46125
+ * new HTTP request.
46126
+ *
46127
+ * @api protected
46128
+ */
46129
+ callback(req, opts) {
46130
+ return __awaiter4(this, void 0, void 0, function* () {
46131
+ const { proxy, secureProxy } = this;
46132
+ let socket;
46133
+ if (secureProxy) {
46134
+ debug("Creating `tls.Socket`: %o", proxy);
46135
+ socket = tls_1.default.connect(proxy);
46136
+ } else {
46137
+ debug("Creating `net.Socket`: %o", proxy);
46138
+ socket = net_1.default.connect(proxy);
46139
+ }
46140
+ const headers = Object.assign({}, proxy.headers);
46141
+ const hostname4 = `${opts.host}:${opts.port}`;
46142
+ let payload = `CONNECT ${hostname4} HTTP/1.1\r
46143
+ `;
46144
+ if (proxy.auth) {
46145
+ headers["Proxy-Authorization"] = `Basic ${Buffer.from(proxy.auth).toString("base64")}`;
46146
+ }
46147
+ let { host, port, secureEndpoint } = opts;
46148
+ if (!isDefaultPort(port, secureEndpoint)) {
46149
+ host += `:${port}`;
46150
+ }
46151
+ headers.Host = host;
46152
+ headers.Connection = "close";
46153
+ for (const name of Object.keys(headers)) {
46154
+ payload += `${name}: ${headers[name]}\r
46155
+ `;
46156
+ }
46157
+ const proxyResponsePromise = parse_proxy_response_1.default(socket);
46158
+ socket.write(`${payload}\r
46159
+ `);
46160
+ const { statusCode, buffered } = yield proxyResponsePromise;
46161
+ if (statusCode === 200) {
46162
+ req.once("socket", resume);
46163
+ if (opts.secureEndpoint) {
46164
+ debug("Upgrading socket connection to TLS");
46165
+ const servername = opts.servername || opts.host;
46166
+ return tls_1.default.connect(Object.assign(Object.assign({}, omit4(opts, "host", "hostname", "path", "port")), {
46167
+ socket,
46168
+ servername
46169
+ }));
46170
+ }
46171
+ return socket;
46172
+ }
46173
+ socket.destroy();
46174
+ const fakeSocket = new net_1.default.Socket({ writable: false });
46175
+ fakeSocket.readable = true;
46176
+ req.once("socket", (s) => {
46177
+ debug("replaying proxy buffer for failed request");
46178
+ assert_1.default(s.listenerCount("data") > 0);
46179
+ s.push(buffered);
46180
+ s.push(null);
46181
+ });
46182
+ return fakeSocket;
46183
+ });
46184
+ }
46185
+ };
46186
+ exports$1.default = HttpsProxyAgent2;
46187
+ function resume(socket) {
46188
+ socket.resume();
46189
+ }
46190
+ function isDefaultPort(port, secure) {
46191
+ return Boolean(!secure && port === 80 || secure && port === 443);
46192
+ }
46193
+ function isHTTPS(protocol) {
46194
+ return typeof protocol === "string" ? /^https:?$/i.test(protocol) : false;
46195
+ }
46196
+ function omit4(obj, ...keys) {
46197
+ const ret = {};
46198
+ let key;
46199
+ for (key in obj) {
46200
+ if (!keys.includes(key)) {
46201
+ ret[key] = obj[key];
46202
+ }
46203
+ }
46204
+ return ret;
46205
+ }
46206
+ }
46207
+ });
46208
+ var require_dist2 = __commonJS({
46209
+ "../../node_modules/.pnpm/https-proxy-agent@5.0.1/node_modules/https-proxy-agent/dist/index.js"(exports$1, module) {
46210
+ var __importDefault = exports$1 && exports$1.__importDefault || function(mod5) {
46211
+ return mod5 && mod5.__esModule ? mod5 : { "default": mod5 };
46212
+ };
46213
+ var agent_1 = __importDefault(require_agent());
46214
+ function createHttpsProxyAgent(opts) {
46215
+ return new agent_1.default(opts);
46216
+ }
46217
+ (function(createHttpsProxyAgent2) {
46218
+ createHttpsProxyAgent2.HttpsProxyAgent = agent_1.default;
46219
+ createHttpsProxyAgent2.prototype = agent_1.default.prototype;
46220
+ })(createHttpsProxyAgent || (createHttpsProxyAgent = {}));
46221
+ module.exports = createHttpsProxyAgent;
46222
+ }
46223
+ });
45698
46224
  var require_debug = __commonJS({
45699
- "../../node_modules/.pnpm/follow-redirects@1.15.11/node_modules/follow-redirects/debug.js"(exports$1, module) {
46225
+ "../../node_modules/.pnpm/follow-redirects@1.16.0/node_modules/follow-redirects/debug.js"(exports$1, module) {
45700
46226
  var debug;
45701
46227
  module.exports = function() {
45702
46228
  if (!debug) {
@@ -45714,7 +46240,7 @@ var require_debug = __commonJS({
45714
46240
  }
45715
46241
  });
45716
46242
  var require_follow_redirects = __commonJS({
45717
- "../../node_modules/.pnpm/follow-redirects@1.15.11/node_modules/follow-redirects/index.js"(exports$1, module) {
46243
+ "../../node_modules/.pnpm/follow-redirects@1.16.0/node_modules/follow-redirects/index.js"(exports$1, module) {
45718
46244
  var url3 = __require("url");
45719
46245
  var URL3 = url3.URL;
45720
46246
  var http6 = __require("http");
@@ -45736,6 +46262,11 @@ var require_follow_redirects = __commonJS({
45736
46262
  } catch (error52) {
45737
46263
  useNativeURL = error52.code === "ERR_INVALID_URL";
45738
46264
  }
46265
+ var sensitiveHeaders = [
46266
+ "Authorization",
46267
+ "Proxy-Authorization",
46268
+ "Cookie"
46269
+ ];
45739
46270
  var preservedUrlFields = [
45740
46271
  "auth",
45741
46272
  "host",
@@ -45800,6 +46331,7 @@ var require_follow_redirects = __commonJS({
45800
46331
  self2.emit("error", cause instanceof RedirectionError ? cause : new RedirectionError({ cause }));
45801
46332
  }
45802
46333
  };
46334
+ this._headerFilter = new RegExp("^(?:" + sensitiveHeaders.concat(options.sensitiveHeaders).map(escapeRegex3).join("|") + ")$", "i");
45803
46335
  this._performRequest();
45804
46336
  }
45805
46337
  RedirectableRequest.prototype = Object.create(Writable.prototype);
@@ -45937,6 +46469,9 @@ var require_follow_redirects = __commonJS({
45937
46469
  if (!options.headers) {
45938
46470
  options.headers = {};
45939
46471
  }
46472
+ if (!isArray2(options.sensitiveHeaders)) {
46473
+ options.sensitiveHeaders = [];
46474
+ }
45940
46475
  if (options.host) {
45941
46476
  if (!options.hostname) {
45942
46477
  options.hostname = options.host;
@@ -46042,7 +46577,7 @@ var require_follow_redirects = __commonJS({
46042
46577
  this._isRedirect = true;
46043
46578
  spreadUrlObject(redirectUrl, this._options);
46044
46579
  if (redirectUrl.protocol !== currentUrlParts.protocol && redirectUrl.protocol !== "https:" || redirectUrl.host !== currentHost && !isSubdomain(redirectUrl.host, currentHost)) {
46045
- removeMatchingHeaders(/^(?:(?:proxy-)?authorization|cookie)$/i, this._options.headers);
46580
+ removeMatchingHeaders(this._headerFilter, this._options.headers);
46046
46581
  }
46047
46582
  if (isFunction3(beforeRedirect)) {
46048
46583
  var responseDetails = {
@@ -46191,6 +46726,9 @@ var require_follow_redirects = __commonJS({
46191
46726
  var dot = subdomain.length - domain2.length - 1;
46192
46727
  return dot > 0 && subdomain[dot] === "." && subdomain.endsWith(domain2);
46193
46728
  }
46729
+ function isArray2(value) {
46730
+ return value instanceof Array;
46731
+ }
46194
46732
  function isString2(value) {
46195
46733
  return typeof value === "string" || value instanceof String;
46196
46734
  }
@@ -46203,22 +46741,25 @@ var require_follow_redirects = __commonJS({
46203
46741
  function isURL(value) {
46204
46742
  return URL3 && value instanceof URL3;
46205
46743
  }
46744
+ function escapeRegex3(regex) {
46745
+ return regex.replace(/[\]\\/()*+?.$]/g, "\\$&");
46746
+ }
46206
46747
  module.exports = wrap4({ http: http6, https: https3 });
46207
46748
  module.exports.wrap = wrap4;
46208
46749
  }
46209
46750
  });
46210
46751
  var VERSION;
46211
46752
  var init_data = __esm({
46212
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/env/data.js"() {
46213
- VERSION = "1.15.2";
46753
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/env/data.js"() {
46754
+ VERSION = "1.16.1";
46214
46755
  }
46215
46756
  });
46216
46757
  function parseProtocol(url3) {
46217
- const match = /^([-+\w]{1,25})(:?\/\/|:)/.exec(url3);
46758
+ const match = /^([-+\w]{1,25}):(?:\/\/)?/.exec(url3);
46218
46759
  return match && match[1] || "";
46219
46760
  }
46220
46761
  var init_parseProtocol = __esm({
46221
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/parseProtocol.js"() {
46762
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/parseProtocol.js"() {
46222
46763
  }
46223
46764
  });
46224
46765
  function fromDataURI(uri, asBlob, options) {
@@ -46233,10 +46774,17 @@ function fromDataURI(uri, asBlob, options) {
46233
46774
  if (!match) {
46234
46775
  throw new AxiosError_default("Invalid URL", AxiosError_default.ERR_INVALID_URL);
46235
46776
  }
46236
- const mime = match[1];
46237
- const isBase64 = match[2];
46238
- const body2 = match[3];
46239
- const buffer2 = Buffer.from(decodeURIComponent(body2), isBase64 ? "base64" : "utf8");
46777
+ const type2 = match[1];
46778
+ const params = match[2];
46779
+ const encoding = match[3] ? "base64" : "utf8";
46780
+ const body2 = match[4];
46781
+ let mime;
46782
+ if (type2) {
46783
+ mime = params ? type2 + params : type2;
46784
+ } else if (params) {
46785
+ mime = "text/plain" + params;
46786
+ }
46787
+ const buffer2 = Buffer.from(decodeURIComponent(body2), encoding);
46240
46788
  if (asBlob) {
46241
46789
  if (!_Blob) {
46242
46790
  throw new AxiosError_default("Blob is not supported", AxiosError_default.ERR_NOT_SUPPORT);
@@ -46249,18 +46797,18 @@ function fromDataURI(uri, asBlob, options) {
46249
46797
  }
46250
46798
  var DATA_URL_PATTERN;
46251
46799
  var init_fromDataURI = __esm({
46252
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/fromDataURI.js"() {
46800
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/fromDataURI.js"() {
46253
46801
  init_AxiosError();
46254
46802
  init_parseProtocol();
46255
46803
  init_platform();
46256
- DATA_URL_PATTERN = /^(?:([^;]+);)?(?:[^;]+;)?(base64|),([\s\S]*)$/;
46804
+ DATA_URL_PATTERN = /^([^,;]+\/[^,;]+)?((?:;[^,;=]+=[^,;]+)*)(;base64)?,([\s\S]*)$/;
46257
46805
  }
46258
46806
  });
46259
46807
  var kInternals;
46260
46808
  var AxiosTransformStream;
46261
46809
  var AxiosTransformStream_default;
46262
46810
  var init_AxiosTransformStream = __esm({
46263
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/AxiosTransformStream.js"() {
46811
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/AxiosTransformStream.js"() {
46264
46812
  init_utils7();
46265
46813
  kInternals = /* @__PURE__ */ Symbol("internals");
46266
46814
  AxiosTransformStream = class extends stream3.Transform {
@@ -46388,7 +46936,7 @@ var asyncIterator;
46388
46936
  var readBlob;
46389
46937
  var readBlob_default;
46390
46938
  var init_readBlob = __esm({
46391
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/readBlob.js"() {
46939
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/readBlob.js"() {
46392
46940
  ({ asyncIterator } = Symbol);
46393
46941
  readBlob = async function* (blob) {
46394
46942
  if (blob.stream) {
@@ -46413,7 +46961,7 @@ var FormDataPart;
46413
46961
  var formDataToStream;
46414
46962
  var formDataToStream_default;
46415
46963
  var init_formDataToStream = __esm({
46416
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/formDataToStream.js"() {
46964
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/formDataToStream.js"() {
46417
46965
  init_utils7();
46418
46966
  init_readBlob();
46419
46967
  init_platform();
@@ -46470,7 +47018,7 @@ var init_formDataToStream = __esm({
46470
47018
  throw TypeError("FormData instance required");
46471
47019
  }
46472
47020
  if (boundary.length < 1 || boundary.length > 70) {
46473
- throw Error("boundary must be 10-70 characters long");
47021
+ throw Error("boundary must be 1-70 characters long");
46474
47022
  }
46475
47023
  const boundaryBytes = textEncoder.encode("--" + boundary + CRLF);
46476
47024
  const footerBytes = textEncoder.encode("--" + boundary + "--" + CRLF);
@@ -46505,7 +47053,7 @@ var init_formDataToStream = __esm({
46505
47053
  var ZlibHeaderTransformStream;
46506
47054
  var ZlibHeaderTransformStream_default;
46507
47055
  var init_ZlibHeaderTransformStream = __esm({
46508
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/ZlibHeaderTransformStream.js"() {
47056
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/ZlibHeaderTransformStream.js"() {
46509
47057
  ZlibHeaderTransformStream = class extends stream3.Transform {
46510
47058
  __transform(chunk2, encoding, callback) {
46511
47059
  this.push(chunk2);
@@ -46530,7 +47078,7 @@ var init_ZlibHeaderTransformStream = __esm({
46530
47078
  var callbackify;
46531
47079
  var callbackify_default;
46532
47080
  var init_callbackify = __esm({
46533
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/callbackify.js"() {
47081
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/callbackify.js"() {
46534
47082
  init_utils7();
46535
47083
  callbackify = (fn, reducer) => {
46536
47084
  return utils_default.isAsyncFn(fn) ? function(...args) {
@@ -46590,9 +47138,12 @@ var isIPv6Loopback;
46590
47138
  var isLoopback;
46591
47139
  var DEFAULT_PORTS2;
46592
47140
  var parseNoProxyEntry;
47141
+ var IPV4_MAPPED_DOTTED_RE;
47142
+ var IPV4_MAPPED_HEX_RE;
47143
+ var unmapIPv4MappedIPv6;
46593
47144
  var normalizeNoProxyHost;
46594
47145
  var init_shouldBypassProxy = __esm({
46595
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/shouldBypassProxy.js"() {
47146
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/shouldBypassProxy.js"() {
46596
47147
  LOOPBACK_HOSTNAMES = /* @__PURE__ */ new Set(["localhost"]);
46597
47148
  isIPv4Loopback = (host) => {
46598
47149
  const parts = host.split(".");
@@ -46653,6 +47204,20 @@ var init_shouldBypassProxy = __esm({
46653
47204
  }
46654
47205
  return [entryHost, entryPort];
46655
47206
  };
47207
+ IPV4_MAPPED_DOTTED_RE = /^(?:::|(?:0{1,4}:){1,4}:|(?:0{1,4}:){5})ffff:(\d+\.\d+\.\d+\.\d+)$/i;
47208
+ IPV4_MAPPED_HEX_RE = /^(?:::|(?:0{1,4}:){1,4}:|(?:0{1,4}:){5})ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i;
47209
+ unmapIPv4MappedIPv6 = (host) => {
47210
+ if (typeof host !== "string" || host.indexOf(":") === -1) return host;
47211
+ const dotted = host.match(IPV4_MAPPED_DOTTED_RE);
47212
+ if (dotted) return dotted[1];
47213
+ const hex3 = host.match(IPV4_MAPPED_HEX_RE);
47214
+ if (hex3) {
47215
+ const high = parseInt(hex3[1], 16);
47216
+ const low = parseInt(hex3[2], 16);
47217
+ return `${high >> 8}.${high & 255}.${low >> 8}.${low & 255}`;
47218
+ }
47219
+ return host;
47220
+ };
46656
47221
  normalizeNoProxyHost = (hostname4) => {
46657
47222
  if (!hostname4) {
46658
47223
  return hostname4;
@@ -46660,7 +47225,7 @@ var init_shouldBypassProxy = __esm({
46660
47225
  if (hostname4.charAt(0) === "[" && hostname4.charAt(hostname4.length - 1) === "]") {
46661
47226
  hostname4 = hostname4.slice(1, -1);
46662
47227
  }
46663
- return hostname4.replace(/\.+$/, "");
47228
+ return unmapIPv4MappedIPv6(hostname4.replace(/\.+$/, ""));
46664
47229
  };
46665
47230
  }
46666
47231
  });
@@ -46699,7 +47264,7 @@ function speedometer(samplesCount, min2) {
46699
47264
  }
46700
47265
  var speedometer_default;
46701
47266
  var init_speedometer = __esm({
46702
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/speedometer.js"() {
47267
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/speedometer.js"() {
46703
47268
  speedometer_default = speedometer;
46704
47269
  }
46705
47270
  });
@@ -46737,7 +47302,7 @@ function throttle(fn, freq) {
46737
47302
  }
46738
47303
  var throttle_default;
46739
47304
  var init_throttle = __esm({
46740
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/throttle.js"() {
47305
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/throttle.js"() {
46741
47306
  throttle_default = throttle;
46742
47307
  }
46743
47308
  });
@@ -46745,7 +47310,7 @@ var progressEventReducer;
46745
47310
  var progressEventDecorator;
46746
47311
  var asyncDecorator;
46747
47312
  var init_progressEventReducer = __esm({
46748
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/progressEventReducer.js"() {
47313
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/progressEventReducer.js"() {
46749
47314
  init_speedometer();
46750
47315
  init_throttle();
46751
47316
  init_utils7();
@@ -46753,6 +47318,9 @@ var init_progressEventReducer = __esm({
46753
47318
  let bytesNotified = 0;
46754
47319
  const _speedometer = speedometer_default(50, 250);
46755
47320
  return throttle_default((e) => {
47321
+ if (!e || typeof e.loaded !== "number") {
47322
+ return;
47323
+ }
46756
47324
  const rawLoaded = e.loaded;
46757
47325
  const total = e.lengthComputable ? e.total : void 0;
46758
47326
  const loaded = total != null ? Math.min(rawLoaded, total) : rawLoaded;
@@ -46831,24 +47399,68 @@ function estimateDataURLDecodedBytes(url3) {
46831
47399
  }
46832
47400
  }
46833
47401
  const groups = Math.floor(effectiveLen / 4);
46834
- const bytes = groups * 3 - (pad6 || 0);
46835
- return bytes > 0 ? bytes : 0;
47402
+ const bytes2 = groups * 3 - (pad6 || 0);
47403
+ return bytes2 > 0 ? bytes2 : 0;
47404
+ }
47405
+ if (typeof Buffer !== "undefined" && typeof Buffer.byteLength === "function") {
47406
+ return Buffer.byteLength(body2, "utf8");
47407
+ }
47408
+ let bytes = 0;
47409
+ for (let i = 0, len = body2.length; i < len; i++) {
47410
+ const c = body2.charCodeAt(i);
47411
+ if (c < 128) {
47412
+ bytes += 1;
47413
+ } else if (c < 2048) {
47414
+ bytes += 2;
47415
+ } else if (c >= 55296 && c <= 56319 && i + 1 < len) {
47416
+ const next = body2.charCodeAt(i + 1);
47417
+ if (next >= 56320 && next <= 57343) {
47418
+ bytes += 4;
47419
+ i++;
47420
+ } else {
47421
+ bytes += 3;
47422
+ }
47423
+ } else {
47424
+ bytes += 3;
47425
+ }
46836
47426
  }
46837
- return Buffer.byteLength(body2, "utf8");
47427
+ return bytes;
46838
47428
  }
46839
47429
  var init_estimateDataURLDecodedBytes = __esm({
46840
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js"() {
47430
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js"() {
46841
47431
  }
46842
47432
  });
46843
- function dispatchBeforeRedirect(options, responseDetails) {
47433
+ function setFormDataHeaders(headers, formHeaders, policy) {
47434
+ if (policy !== "content-only") {
47435
+ headers.set(formHeaders);
47436
+ return;
47437
+ }
47438
+ Object.entries(formHeaders).forEach(([key, val]) => {
47439
+ if (FORM_DATA_CONTENT_HEADERS.includes(key.toLowerCase())) {
47440
+ headers.set(key, val);
47441
+ }
47442
+ });
47443
+ }
47444
+ function getTunnelingAgent(agentOptions, userHttpsAgent) {
47445
+ const key = agentOptions.protocol + "//" + agentOptions.hostname + ":" + (agentOptions.port || "") + "#" + (agentOptions.auth || "");
47446
+ const cache = userHttpsAgent ? tunnelingAgentCacheUser.get(userHttpsAgent) || tunnelingAgentCacheUser.set(userHttpsAgent, /* @__PURE__ */ new Map()).get(userHttpsAgent) : tunnelingAgentCache;
47447
+ let agent = cache.get(key);
47448
+ if (agent) return agent;
47449
+ const merged = userHttpsAgent && userHttpsAgent.options ? { ...userHttpsAgent.options, ...agentOptions } : agentOptions;
47450
+ agent = new import_https_proxy_agent.default(merged);
47451
+ agent[kAxiosInstalledTunnel] = true;
47452
+ cache.set(key, agent);
47453
+ return agent;
47454
+ }
47455
+ function dispatchBeforeRedirect(options, responseDetails, requestDetails) {
46844
47456
  if (options.beforeRedirects.proxy) {
46845
47457
  options.beforeRedirects.proxy(options);
46846
47458
  }
46847
47459
  if (options.beforeRedirects.config) {
46848
- options.beforeRedirects.config(options, responseDetails);
47460
+ options.beforeRedirects.config(options, responseDetails, requestDetails);
46849
47461
  }
46850
47462
  }
46851
- function setProxy(options, configProxy, location) {
47463
+ function setProxy(options, configProxy, location, isRedirect, configHttpsAgent) {
46852
47464
  let proxy = configProxy;
46853
47465
  if (!proxy && proxy !== false) {
46854
47466
  const proxyUrl = getProxyForUrl(location);
@@ -46858,34 +47470,93 @@ function setProxy(options, configProxy, location) {
46858
47470
  }
46859
47471
  }
46860
47472
  }
46861
- if (proxy) {
46862
- if (proxy.username) {
46863
- proxy.auth = (proxy.username || "") + ":" + (proxy.password || "");
47473
+ if (isRedirect && options.headers) {
47474
+ for (const name of Object.keys(options.headers)) {
47475
+ if (name.toLowerCase() === "proxy-authorization") {
47476
+ delete options.headers[name];
47477
+ }
46864
47478
  }
46865
- if (proxy.auth) {
46866
- const validProxyAuth = Boolean(proxy.auth.username || proxy.auth.password);
47479
+ }
47480
+ if (isRedirect && options.agent && options.agent[kAxiosInstalledTunnel]) {
47481
+ options.agent = void 0;
47482
+ }
47483
+ if (proxy) {
47484
+ const isProxyURL = proxy instanceof URL;
47485
+ const readProxyField = (key) => isProxyURL || utils_default.hasOwnProp(proxy, key) ? proxy[key] : void 0;
47486
+ const proxyUsername = readProxyField("username");
47487
+ const proxyPassword = readProxyField("password");
47488
+ let proxyAuth = utils_default.hasOwnProp(proxy, "auth") ? proxy.auth : void 0;
47489
+ if (proxyUsername) {
47490
+ proxyAuth = (proxyUsername || "") + ":" + (proxyPassword || "");
47491
+ }
47492
+ if (proxyAuth) {
47493
+ const authIsObject = typeof proxyAuth === "object";
47494
+ const authUsername = authIsObject && utils_default.hasOwnProp(proxyAuth, "username") ? proxyAuth.username : void 0;
47495
+ const authPassword = authIsObject && utils_default.hasOwnProp(proxyAuth, "password") ? proxyAuth.password : void 0;
47496
+ const validProxyAuth = Boolean(authUsername || authPassword);
46867
47497
  if (validProxyAuth) {
46868
- proxy.auth = (proxy.auth.username || "") + ":" + (proxy.auth.password || "");
46869
- } else if (typeof proxy.auth === "object") {
47498
+ proxyAuth = (authUsername || "") + ":" + (authPassword || "");
47499
+ } else if (authIsObject) {
46870
47500
  throw new AxiosError_default("Invalid proxy authorization", AxiosError_default.ERR_BAD_OPTION, { proxy });
46871
47501
  }
46872
- const base644 = Buffer.from(proxy.auth, "utf8").toString("base64");
46873
- options.headers["Proxy-Authorization"] = "Basic " + base644;
46874
47502
  }
46875
- options.headers.host = options.hostname + (options.port ? ":" + options.port : "");
46876
- const proxyHost = proxy.hostname || proxy.host;
46877
- options.hostname = proxyHost;
46878
- options.host = proxyHost;
46879
- options.port = proxy.port;
46880
- options.path = location;
46881
- if (proxy.protocol) {
46882
- options.protocol = proxy.protocol.includes(":") ? proxy.protocol : `${proxy.protocol}:`;
47503
+ const targetIsHttps = isHttps.test(options.protocol);
47504
+ if (targetIsHttps) {
47505
+ if (!(configHttpsAgent instanceof import_https_proxy_agent.default)) {
47506
+ const proxyHost = readProxyField("hostname") || readProxyField("host");
47507
+ const proxyPort = readProxyField("port");
47508
+ const rawProxyProtocol = readProxyField("protocol");
47509
+ const normalizedProtocol = rawProxyProtocol ? rawProxyProtocol.includes(":") ? rawProxyProtocol : `${rawProxyProtocol}:` : "http:";
47510
+ const proxyHostForURL = proxyHost && proxyHost.includes(":") && !proxyHost.startsWith("[") ? `[${proxyHost}]` : proxyHost;
47511
+ const proxyURL = new URL(
47512
+ `${normalizedProtocol}//${proxyHostForURL}${proxyPort ? ":" + proxyPort : ""}`
47513
+ );
47514
+ const agentOptions = {
47515
+ protocol: proxyURL.protocol,
47516
+ hostname: proxyURL.hostname.replace(/^\[|\]$/g, ""),
47517
+ port: proxyURL.port,
47518
+ auth: proxyAuth && typeof proxyAuth === "string" ? proxyAuth : void 0
47519
+ };
47520
+ if (proxyURL.protocol === "https:") {
47521
+ agentOptions.ALPNProtocols = ["http/1.1"];
47522
+ }
47523
+ const tunnelingAgent = getTunnelingAgent(agentOptions, configHttpsAgent);
47524
+ options.agent = tunnelingAgent;
47525
+ if (options.agents) {
47526
+ options.agents.https = tunnelingAgent;
47527
+ }
47528
+ }
47529
+ } else {
47530
+ if (proxyAuth) {
47531
+ const base644 = Buffer.from(proxyAuth, "utf8").toString("base64");
47532
+ options.headers["Proxy-Authorization"] = "Basic " + base644;
47533
+ }
47534
+ let hasUserHostHeader = false;
47535
+ for (const name of Object.keys(options.headers)) {
47536
+ if (name.toLowerCase() === "host") {
47537
+ hasUserHostHeader = true;
47538
+ break;
47539
+ }
47540
+ }
47541
+ if (!hasUserHostHeader) {
47542
+ options.headers.host = options.hostname + (options.port ? ":" + options.port : "");
47543
+ }
47544
+ const proxyHost = readProxyField("hostname") || readProxyField("host");
47545
+ options.hostname = proxyHost;
47546
+ options.host = proxyHost;
47547
+ options.port = readProxyField("port");
47548
+ options.path = location;
47549
+ const proxyProtocol = readProxyField("protocol");
47550
+ if (proxyProtocol) {
47551
+ options.protocol = proxyProtocol.includes(":") ? proxyProtocol : `${proxyProtocol}:`;
47552
+ }
46883
47553
  }
46884
47554
  }
46885
47555
  options.beforeRedirects.proxy = function beforeRedirect(redirectOptions) {
46886
- setProxy(redirectOptions, configProxy, redirectOptions.href);
47556
+ setProxy(redirectOptions, configProxy, redirectOptions.href, true, configHttpsAgent);
46887
47557
  };
46888
47558
  }
47559
+ var import_https_proxy_agent;
46889
47560
  var import_follow_redirects;
46890
47561
  var zlibOptions;
46891
47562
  var brotliOptions;
@@ -46893,9 +47564,14 @@ var isBrotliSupported;
46893
47564
  var httpFollow;
46894
47565
  var httpsFollow;
46895
47566
  var isHttps;
47567
+ var FORM_DATA_CONTENT_HEADERS;
46896
47568
  var kAxiosSocketListener;
46897
47569
  var kAxiosCurrentReq;
47570
+ var kAxiosInstalledTunnel;
47571
+ var tunnelingAgentCache;
47572
+ var tunnelingAgentCacheUser;
46898
47573
  var supportedProtocols;
47574
+ var decodeURIComponentSafe;
46899
47575
  var flushOnFinish;
46900
47576
  var Http2Sessions;
46901
47577
  var http2Sessions;
@@ -46906,12 +47582,13 @@ var buildAddressEntry;
46906
47582
  var http2Transport;
46907
47583
  var http_default;
46908
47584
  var init_http = __esm({
46909
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/adapters/http.js"() {
47585
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/adapters/http.js"() {
46910
47586
  init_utils7();
46911
47587
  init_settle();
46912
47588
  init_buildFullPath();
46913
47589
  init_buildURL();
46914
47590
  init_proxy_from_env();
47591
+ import_https_proxy_agent = __toESM(require_dist2());
46915
47592
  import_follow_redirects = __toESM(require_follow_redirects());
46916
47593
  init_data();
46917
47594
  init_transitional();
@@ -46926,6 +47603,7 @@ var init_http = __esm({
46926
47603
  init_ZlibHeaderTransformStream();
46927
47604
  init_callbackify();
46928
47605
  init_shouldBypassProxy();
47606
+ init_sanitizeHeaderValue();
46929
47607
  init_progressEventReducer();
46930
47608
  init_estimateDataURLDecodedBytes();
46931
47609
  zlibOptions = {
@@ -46939,11 +47617,25 @@ var init_http = __esm({
46939
47617
  isBrotliSupported = utils_default.isFunction(zlib.createBrotliDecompress);
46940
47618
  ({ http: httpFollow, https: httpsFollow } = import_follow_redirects.default);
46941
47619
  isHttps = /https:?/;
47620
+ FORM_DATA_CONTENT_HEADERS = ["content-type", "content-length"];
46942
47621
  kAxiosSocketListener = /* @__PURE__ */ Symbol("axios.http.socketListener");
46943
47622
  kAxiosCurrentReq = /* @__PURE__ */ Symbol("axios.http.currentReq");
47623
+ kAxiosInstalledTunnel = /* @__PURE__ */ Symbol("axios.http.installedTunnel");
47624
+ tunnelingAgentCache = /* @__PURE__ */ new Map();
47625
+ tunnelingAgentCacheUser = /* @__PURE__ */ new WeakMap();
46944
47626
  supportedProtocols = platform_default.protocols.map((protocol) => {
46945
47627
  return protocol + ":";
46946
47628
  });
47629
+ decodeURIComponentSafe = (value) => {
47630
+ if (!utils_default.isString(value)) {
47631
+ return value;
47632
+ }
47633
+ try {
47634
+ return decodeURIComponent(value);
47635
+ } catch (error52) {
47636
+ return value;
47637
+ }
47638
+ };
46947
47639
  flushOnFinish = (stream4, [throttled, flush]) => {
46948
47640
  stream4.on("end", flush).on("error", flush);
46949
47641
  return throttled;
@@ -47094,6 +47786,7 @@ var init_http = __esm({
47094
47786
  let isDone;
47095
47787
  let rejected = false;
47096
47788
  let req;
47789
+ let connectPhaseTimer;
47097
47790
  httpVersion = +httpVersion;
47098
47791
  if (Number.isNaN(httpVersion)) {
47099
47792
  throw TypeError(`Invalid protocol version: '${config4.httpVersion}' is not a number`);
@@ -47125,8 +47818,28 @@ var init_http = __esm({
47125
47818
  console.warn("emit error", err);
47126
47819
  }
47127
47820
  }
47821
+ function clearConnectPhaseTimer() {
47822
+ if (connectPhaseTimer) {
47823
+ clearTimeout(connectPhaseTimer);
47824
+ connectPhaseTimer = null;
47825
+ }
47826
+ }
47827
+ function createTimeoutError() {
47828
+ let timeoutErrorMessage = config4.timeout ? "timeout of " + config4.timeout + "ms exceeded" : "timeout exceeded";
47829
+ const transitional2 = config4.transitional || transitional_default;
47830
+ if (config4.timeoutErrorMessage) {
47831
+ timeoutErrorMessage = config4.timeoutErrorMessage;
47832
+ }
47833
+ return new AxiosError_default(
47834
+ timeoutErrorMessage,
47835
+ transitional2.clarifyTimeoutError ? AxiosError_default.ETIMEDOUT : AxiosError_default.ECONNABORTED,
47836
+ config4,
47837
+ req
47838
+ );
47839
+ }
47128
47840
  abortEmitter.once("abort", reject);
47129
47841
  const onFinished = () => {
47842
+ clearConnectPhaseTimer();
47130
47843
  if (config4.cancelToken) {
47131
47844
  config4.cancelToken.unsubscribe(abort);
47132
47845
  }
@@ -47143,6 +47856,7 @@ var init_http = __esm({
47143
47856
  }
47144
47857
  onDone((response, isRejected) => {
47145
47858
  isDone = true;
47859
+ clearConnectPhaseTimer();
47146
47860
  if (isRejected) {
47147
47861
  rejected = true;
47148
47862
  onFinished();
@@ -47231,7 +47945,7 @@ var init_http = __esm({
47231
47945
  }
47232
47946
  );
47233
47947
  } else if (utils_default.isFormData(data) && utils_default.isFunction(data.getHeaders) && data.getHeaders !== Object.prototype.getHeaders) {
47234
- headers.set(data.getHeaders());
47948
+ setFormDataHeaders(headers, data.getHeaders(), own2("formDataHeaderPolicy"));
47235
47949
  if (!headers.hasContentLength()) {
47236
47950
  try {
47237
47951
  const knownLength = await util3.promisify(data.getLength).call(data);
@@ -47308,8 +48022,8 @@ var init_http = __esm({
47308
48022
  auth = username + ":" + password;
47309
48023
  }
47310
48024
  if (!auth && parsed.username) {
47311
- const urlUsername = parsed.username;
47312
- const urlPassword = parsed.password;
48025
+ const urlUsername = decodeURIComponentSafe(parsed.username);
48026
+ const urlPassword = decodeURIComponentSafe(parsed.password);
47313
48027
  auth = urlUsername + ":" + urlPassword;
47314
48028
  }
47315
48029
  auth && headers.delete("authorization");
@@ -47335,7 +48049,7 @@ var init_http = __esm({
47335
48049
  const options = Object.assign(/* @__PURE__ */ Object.create(null), {
47336
48050
  path,
47337
48051
  method,
47338
- headers: headers.toJSON(),
48052
+ headers: toByteStringHeaderObject(headers),
47339
48053
  agents: { http: config4.httpAgent, https: config4.httpsAgent },
47340
48054
  auth,
47341
48055
  protocol,
@@ -47347,11 +48061,9 @@ var init_http = __esm({
47347
48061
  !utils_default.isUndefined(lookup) && (options.lookup = lookup);
47348
48062
  if (config4.socketPath) {
47349
48063
  if (typeof config4.socketPath !== "string") {
47350
- return reject(new AxiosError_default(
47351
- "socketPath must be a string",
47352
- AxiosError_default.ERR_BAD_OPTION_VALUE,
47353
- config4
47354
- ));
48064
+ return reject(
48065
+ new AxiosError_default("socketPath must be a string", AxiosError_default.ERR_BAD_OPTION_VALUE, config4)
48066
+ );
47355
48067
  }
47356
48068
  if (config4.allowedSocketPaths != null) {
47357
48069
  const allowed = Array.isArray(config4.allowedSocketPaths) ? config4.allowedSocketPaths : [config4.allowedSocketPaths];
@@ -47360,11 +48072,13 @@ var init_http = __esm({
47360
48072
  (entry) => typeof entry === "string" && resolve$1(entry) === resolvedSocket
47361
48073
  );
47362
48074
  if (!isAllowed) {
47363
- return reject(new AxiosError_default(
47364
- `socketPath "${config4.socketPath}" is not permitted by allowedSocketPaths`,
47365
- AxiosError_default.ERR_BAD_OPTION_VALUE,
47366
- config4
47367
- ));
48075
+ return reject(
48076
+ new AxiosError_default(
48077
+ `socketPath "${config4.socketPath}" is not permitted by allowedSocketPaths`,
48078
+ AxiosError_default.ERR_BAD_OPTION_VALUE,
48079
+ config4
48080
+ )
48081
+ );
47368
48082
  }
47369
48083
  }
47370
48084
  options.socketPath = config4.socketPath;
@@ -47374,12 +48088,17 @@ var init_http = __esm({
47374
48088
  setProxy(
47375
48089
  options,
47376
48090
  config4.proxy,
47377
- protocol + "//" + parsed.hostname + (parsed.port ? ":" + parsed.port : "") + options.path
48091
+ protocol + "//" + parsed.hostname + (parsed.port ? ":" + parsed.port : "") + options.path,
48092
+ false,
48093
+ config4.httpsAgent
47378
48094
  );
47379
48095
  }
47380
48096
  let transport;
48097
+ let isNativeTransport = false;
47381
48098
  const isHttpsRequest = isHttps.test(options.protocol);
47382
- options.agent = isHttpsRequest ? config4.httpsAgent : config4.httpAgent;
48099
+ if (options.agent == null) {
48100
+ options.agent = isHttpsRequest ? config4.httpsAgent : config4.httpAgent;
48101
+ }
47383
48102
  if (isHttp2) {
47384
48103
  transport = http2Transport;
47385
48104
  } else {
@@ -47388,6 +48107,7 @@ var init_http = __esm({
47388
48107
  transport = configTransport;
47389
48108
  } else if (config4.maxRedirects === 0) {
47390
48109
  transport = isHttpsRequest ? https : http5;
48110
+ isNativeTransport = true;
47391
48111
  } else {
47392
48112
  if (config4.maxRedirects) {
47393
48113
  options.maxRedirects = config4.maxRedirects;
@@ -47406,6 +48126,7 @@ var init_http = __esm({
47406
48126
  }
47407
48127
  options.insecureHTTPParser = Boolean(own2("insecureHTTPParser"));
47408
48128
  req = transport.request(options, function handleResponse(res) {
48129
+ clearConnectPhaseTimer();
47409
48130
  if (req.destroyed) return;
47410
48131
  const streams = [res];
47411
48132
  const responseLength = utils_default.toFiniteNumber(res.headers["content-length"]);
@@ -47512,14 +48233,15 @@ var init_http = __esm({
47512
48233
  "stream has been aborted",
47513
48234
  AxiosError_default.ERR_BAD_RESPONSE,
47514
48235
  config4,
47515
- lastRequest
48236
+ lastRequest,
48237
+ response
47516
48238
  );
47517
48239
  responseStream.destroy(err);
47518
48240
  reject(err);
47519
48241
  });
47520
48242
  responseStream.on("error", function handleStreamError(err) {
47521
- if (req.destroyed) return;
47522
- reject(AxiosError_default.from(err, null, config4, lastRequest));
48243
+ if (rejected) return;
48244
+ reject(AxiosError_default.from(err, null, config4, lastRequest, response));
47523
48245
  });
47524
48246
  responseStream.on("end", function handleStreamEnd() {
47525
48247
  try {
@@ -47554,6 +48276,7 @@ var init_http = __esm({
47554
48276
  req.on("error", function handleRequestError(err) {
47555
48277
  reject(AxiosError_default.from(err, null, config4, req));
47556
48278
  });
48279
+ const boundSockets = /* @__PURE__ */ new Set();
47557
48280
  req.on("socket", function handleRequestSocket(socket) {
47558
48281
  socket.setKeepAlive(true, 1e3 * 60);
47559
48282
  if (!socket[kAxiosSocketListener]) {
@@ -47566,11 +48289,16 @@ var init_http = __esm({
47566
48289
  socket[kAxiosSocketListener] = true;
47567
48290
  }
47568
48291
  socket[kAxiosCurrentReq] = req;
47569
- req.once("close", function clearCurrentReq() {
48292
+ boundSockets.add(socket);
48293
+ });
48294
+ req.once("close", function clearCurrentReq() {
48295
+ clearConnectPhaseTimer();
48296
+ for (const socket of boundSockets) {
47570
48297
  if (socket[kAxiosCurrentReq] === req) {
47571
48298
  socket[kAxiosCurrentReq] = null;
47572
48299
  }
47573
- });
48300
+ }
48301
+ boundSockets.clear();
47574
48302
  });
47575
48303
  if (config4.timeout) {
47576
48304
  const timeout = parseInt(config4.timeout, 10);
@@ -47585,22 +48313,14 @@ var init_http = __esm({
47585
48313
  );
47586
48314
  return;
47587
48315
  }
47588
- req.setTimeout(timeout, function handleRequestTimeout() {
48316
+ const handleTimeout = function handleTimeout2() {
47589
48317
  if (isDone) return;
47590
- let timeoutErrorMessage = config4.timeout ? "timeout of " + config4.timeout + "ms exceeded" : "timeout exceeded";
47591
- const transitional2 = config4.transitional || transitional_default;
47592
- if (config4.timeoutErrorMessage) {
47593
- timeoutErrorMessage = config4.timeoutErrorMessage;
47594
- }
47595
- abort(
47596
- new AxiosError_default(
47597
- timeoutErrorMessage,
47598
- transitional2.clarifyTimeoutError ? AxiosError_default.ETIMEDOUT : AxiosError_default.ECONNABORTED,
47599
- config4,
47600
- req
47601
- )
47602
- );
47603
- });
48318
+ abort(createTimeoutError());
48319
+ };
48320
+ if (isNativeTransport && timeout > 0) {
48321
+ connectPhaseTimer = setTimeout(handleTimeout, timeout);
48322
+ }
48323
+ req.setTimeout(timeout, handleTimeout);
47604
48324
  } else {
47605
48325
  req.setTimeout(0);
47606
48326
  }
@@ -47660,7 +48380,7 @@ var init_http = __esm({
47660
48380
  });
47661
48381
  var isURLSameOrigin_default;
47662
48382
  var init_isURLSameOrigin = __esm({
47663
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/isURLSameOrigin.js"() {
48383
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/isURLSameOrigin.js"() {
47664
48384
  init_platform();
47665
48385
  isURLSameOrigin_default = platform_default.hasStandardBrowserEnv ? /* @__PURE__ */ ((origin2, isMSIE) => (url3) => {
47666
48386
  url3 = new URL(url3, platform_default.origin);
@@ -47673,7 +48393,7 @@ var init_isURLSameOrigin = __esm({
47673
48393
  });
47674
48394
  var cookies_default;
47675
48395
  var init_cookies = __esm({
47676
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/cookies.js"() {
48396
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/cookies.js"() {
47677
48397
  init_utils7();
47678
48398
  init_platform();
47679
48399
  cookies_default = platform_default.hasStandardBrowserEnv ? (
@@ -47701,8 +48421,15 @@ var init_cookies = __esm({
47701
48421
  },
47702
48422
  read(name) {
47703
48423
  if (typeof document === "undefined") return null;
47704
- const match = document.cookie.match(new RegExp("(?:^|; )" + name + "=([^;]*)"));
47705
- return match ? decodeURIComponent(match[1]) : null;
48424
+ const cookies = document.cookie.split(";");
48425
+ for (let i = 0; i < cookies.length; i++) {
48426
+ const cookie = cookies[i].replace(/^\s+/, "");
48427
+ const eq = cookie.indexOf("=");
48428
+ if (eq !== -1 && cookie.slice(0, eq) === name) {
48429
+ return decodeURIComponent(cookie.slice(eq + 1));
48430
+ }
48431
+ }
48432
+ return null;
47706
48433
  },
47707
48434
  remove(name) {
47708
48435
  this.write(name, "", Date.now() - 864e5, "/");
@@ -47726,6 +48453,9 @@ function mergeConfig(config1, config22) {
47726
48453
  config22 = config22 || {};
47727
48454
  const config4 = /* @__PURE__ */ Object.create(null);
47728
48455
  Object.defineProperty(config4, "hasOwnProperty", {
48456
+ // Null-proto descriptor so a polluted Object.prototype.get cannot turn
48457
+ // this data descriptor into an accessor descriptor on the way in.
48458
+ __proto__: null,
47729
48459
  value: Object.prototype.hasOwnProperty,
47730
48460
  enumerable: false,
47731
48461
  writable: true,
@@ -47811,15 +48541,28 @@ function mergeConfig(config1, config22) {
47811
48541
  }
47812
48542
  var headersToObject;
47813
48543
  var init_mergeConfig = __esm({
47814
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/core/mergeConfig.js"() {
48544
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/core/mergeConfig.js"() {
47815
48545
  init_utils7();
47816
48546
  init_AxiosHeaders();
47817
48547
  headersToObject = (thing) => thing instanceof AxiosHeaders_default ? { ...thing } : thing;
47818
48548
  }
47819
48549
  });
48550
+ function setFormDataHeaders2(headers, formHeaders, policy) {
48551
+ if (policy !== "content-only") {
48552
+ headers.set(formHeaders);
48553
+ return;
48554
+ }
48555
+ Object.entries(formHeaders).forEach(([key, val]) => {
48556
+ if (FORM_DATA_CONTENT_HEADERS2.includes(key.toLowerCase())) {
48557
+ headers.set(key, val);
48558
+ }
48559
+ });
48560
+ }
48561
+ var FORM_DATA_CONTENT_HEADERS2;
48562
+ var encodeUTF8;
47820
48563
  var resolveConfig_default;
47821
48564
  var init_resolveConfig = __esm({
47822
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/resolveConfig.js"() {
48565
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/resolveConfig.js"() {
47823
48566
  init_platform();
47824
48567
  init_utils7();
47825
48568
  init_isURLSameOrigin();
@@ -47828,6 +48571,11 @@ var init_resolveConfig = __esm({
47828
48571
  init_mergeConfig();
47829
48572
  init_AxiosHeaders();
47830
48573
  init_buildURL();
48574
+ FORM_DATA_CONTENT_HEADERS2 = ["content-type", "content-length"];
48575
+ encodeUTF8 = (str) => encodeURIComponent(str).replace(
48576
+ /%([0-9A-F]{2})/gi,
48577
+ (_, hex3) => String.fromCharCode(parseInt(hex3, 16))
48578
+ );
47831
48579
  resolveConfig_default = (config4) => {
47832
48580
  const newConfig = mergeConfig({}, config4);
47833
48581
  const own2 = (key) => utils_default.hasOwnProp(newConfig, key) ? newConfig[key] : void 0;
@@ -47849,22 +48597,14 @@ var init_resolveConfig = __esm({
47849
48597
  if (auth) {
47850
48598
  headers.set(
47851
48599
  "Authorization",
47852
- "Basic " + btoa(
47853
- (auth.username || "") + ":" + (auth.password ? unescape(encodeURIComponent(auth.password)) : "")
47854
- )
48600
+ "Basic " + btoa((auth.username || "") + ":" + (auth.password ? encodeUTF8(auth.password) : ""))
47855
48601
  );
47856
48602
  }
47857
48603
  if (utils_default.isFormData(data)) {
47858
48604
  if (platform_default.hasStandardBrowserEnv || platform_default.hasStandardBrowserWebWorkerEnv) {
47859
48605
  headers.setContentType(void 0);
47860
48606
  } else if (utils_default.isFunction(data.getHeaders)) {
47861
- const formHeaders = data.getHeaders();
47862
- const allowedHeaders = ["content-type", "content-length"];
47863
- Object.entries(formHeaders).forEach(([key, val]) => {
47864
- if (allowedHeaders.includes(key.toLowerCase())) {
47865
- headers.set(key, val);
47866
- }
47867
- });
48607
+ setFormDataHeaders2(headers, data.getHeaders(), own2("formDataHeaderPolicy"));
47868
48608
  }
47869
48609
  }
47870
48610
  if (platform_default.hasStandardBrowserEnv) {
@@ -47886,7 +48626,7 @@ var init_resolveConfig = __esm({
47886
48626
  var isXHRAdapterSupported;
47887
48627
  var xhr_default;
47888
48628
  var init_xhr = __esm({
47889
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/adapters/xhr.js"() {
48629
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/adapters/xhr.js"() {
47890
48630
  init_utils7();
47891
48631
  init_settle();
47892
48632
  init_transitional();
@@ -47897,6 +48637,7 @@ var init_xhr = __esm({
47897
48637
  init_AxiosHeaders();
47898
48638
  init_progressEventReducer();
47899
48639
  init_resolveConfig();
48640
+ init_sanitizeHeaderValue();
47900
48641
  isXHRAdapterSupported = typeof XMLHttpRequest !== "undefined";
47901
48642
  xhr_default = isXHRAdapterSupported && function(config4) {
47902
48643
  return new Promise(function dispatchXhrRequest(resolve4, reject) {
@@ -47952,7 +48693,7 @@ var init_xhr = __esm({
47952
48693
  if (!request || request.readyState !== 4) {
47953
48694
  return;
47954
48695
  }
47955
- if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf("file:") === 0)) {
48696
+ if (request.status === 0 && !(request.responseURL && request.responseURL.startsWith("file:"))) {
47956
48697
  return;
47957
48698
  }
47958
48699
  setTimeout(onloadend);
@@ -47963,6 +48704,7 @@ var init_xhr = __esm({
47963
48704
  return;
47964
48705
  }
47965
48706
  reject(new AxiosError_default("Request aborted", AxiosError_default.ECONNABORTED, config4, request));
48707
+ done();
47966
48708
  request = null;
47967
48709
  };
47968
48710
  request.onerror = function handleError(event) {
@@ -47970,6 +48712,7 @@ var init_xhr = __esm({
47970
48712
  const err = new AxiosError_default(msg, AxiosError_default.ERR_NETWORK, config4, request);
47971
48713
  err.event = event || null;
47972
48714
  reject(err);
48715
+ done();
47973
48716
  request = null;
47974
48717
  };
47975
48718
  request.ontimeout = function handleTimeout() {
@@ -47986,11 +48729,12 @@ var init_xhr = __esm({
47986
48729
  request
47987
48730
  )
47988
48731
  );
48732
+ done();
47989
48733
  request = null;
47990
48734
  };
47991
48735
  requestData === void 0 && requestHeaders.setContentType(null);
47992
48736
  if ("setRequestHeader" in request) {
47993
- utils_default.forEach(requestHeaders.toJSON(), function setRequestHeader(val, key) {
48737
+ utils_default.forEach(toByteStringHeaderObject(requestHeaders), function setRequestHeader(val, key) {
47994
48738
  request.setRequestHeader(key, val);
47995
48739
  });
47996
48740
  }
@@ -48016,6 +48760,7 @@ var init_xhr = __esm({
48016
48760
  }
48017
48761
  reject(!cancel2 || cancel2.type ? new CanceledError_default(null, config4, request) : cancel2);
48018
48762
  request.abort();
48763
+ done();
48019
48764
  request = null;
48020
48765
  };
48021
48766
  _config.cancelToken && _config.cancelToken.subscribe(onCanceled);
@@ -48024,7 +48769,7 @@ var init_xhr = __esm({
48024
48769
  }
48025
48770
  }
48026
48771
  const protocol = parseProtocol(_config.url);
48027
- if (protocol && platform_default.protocols.indexOf(protocol) === -1) {
48772
+ if (protocol && !platform_default.protocols.includes(protocol)) {
48028
48773
  reject(
48029
48774
  new AxiosError_default(
48030
48775
  "Unsupported protocol " + protocol + ":",
@@ -48042,44 +48787,46 @@ var init_xhr = __esm({
48042
48787
  var composeSignals;
48043
48788
  var composeSignals_default;
48044
48789
  var init_composeSignals = __esm({
48045
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/composeSignals.js"() {
48790
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/composeSignals.js"() {
48046
48791
  init_CanceledError();
48047
48792
  init_AxiosError();
48048
48793
  init_utils7();
48049
48794
  composeSignals = (signals, timeout) => {
48050
- const { length } = signals = signals ? signals.filter(Boolean) : [];
48051
- if (timeout || length) {
48052
- let controller = new AbortController();
48053
- let aborted3;
48054
- const onabort = function(reason) {
48055
- if (!aborted3) {
48056
- aborted3 = true;
48057
- unsubscribe();
48058
- const err = reason instanceof Error ? reason : this.reason;
48059
- controller.abort(
48060
- err instanceof AxiosError_default ? err : new CanceledError_default(err instanceof Error ? err.message : err)
48061
- );
48062
- }
48063
- };
48064
- let timer = timeout && setTimeout(() => {
48065
- timer = null;
48066
- onabort(new AxiosError_default(`timeout of ${timeout}ms exceeded`, AxiosError_default.ETIMEDOUT));
48067
- }, timeout);
48068
- const unsubscribe = () => {
48069
- if (signals) {
48070
- timer && clearTimeout(timer);
48071
- timer = null;
48072
- signals.forEach((signal2) => {
48073
- signal2.unsubscribe ? signal2.unsubscribe(onabort) : signal2.removeEventListener("abort", onabort);
48074
- });
48075
- signals = null;
48076
- }
48077
- };
48078
- signals.forEach((signal2) => signal2.addEventListener("abort", onabort));
48079
- const { signal } = controller;
48080
- signal.unsubscribe = () => utils_default.asap(unsubscribe);
48081
- return signal;
48795
+ signals = signals ? signals.filter(Boolean) : [];
48796
+ if (!timeout && !signals.length) {
48797
+ return;
48082
48798
  }
48799
+ const controller = new AbortController();
48800
+ let aborted3 = false;
48801
+ const onabort = function(reason) {
48802
+ if (!aborted3) {
48803
+ aborted3 = true;
48804
+ unsubscribe();
48805
+ const err = reason instanceof Error ? reason : this.reason;
48806
+ controller.abort(
48807
+ err instanceof AxiosError_default ? err : new CanceledError_default(err instanceof Error ? err.message : err)
48808
+ );
48809
+ }
48810
+ };
48811
+ let timer = timeout && setTimeout(() => {
48812
+ timer = null;
48813
+ onabort(new AxiosError_default(`timeout of ${timeout}ms exceeded`, AxiosError_default.ETIMEDOUT));
48814
+ }, timeout);
48815
+ const unsubscribe = () => {
48816
+ if (!signals) {
48817
+ return;
48818
+ }
48819
+ timer && clearTimeout(timer);
48820
+ timer = null;
48821
+ signals.forEach((signal2) => {
48822
+ signal2.unsubscribe ? signal2.unsubscribe(onabort) : signal2.removeEventListener("abort", onabort);
48823
+ });
48824
+ signals = null;
48825
+ };
48826
+ signals.forEach((signal2) => signal2.addEventListener("abort", onabort));
48827
+ const { signal } = controller;
48828
+ signal.unsubscribe = () => utils_default.asap(unsubscribe);
48829
+ return signal;
48083
48830
  };
48084
48831
  composeSignals_default = composeSignals;
48085
48832
  }
@@ -48089,7 +48836,7 @@ var readBytes;
48089
48836
  var readStream;
48090
48837
  var trackStream;
48091
48838
  var init_trackStream = __esm({
48092
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/trackStream.js"() {
48839
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/trackStream.js"() {
48093
48840
  streamChunk = function* (chunk2, chunkSize) {
48094
48841
  let len = chunk2.byteLength;
48095
48842
  if (!chunkSize || len < chunkSize) {
@@ -48172,15 +48919,12 @@ var init_trackStream = __esm({
48172
48919
  });
48173
48920
  var DEFAULT_CHUNK_SIZE;
48174
48921
  var isFunction2;
48175
- var globalFetchAPI;
48176
- var ReadableStream2;
48177
- var TextEncoder2;
48178
48922
  var test;
48179
48923
  var factory;
48180
48924
  var seedCache;
48181
48925
  var getFetch;
48182
48926
  var init_fetch = __esm({
48183
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/adapters/fetch.js"() {
48927
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/adapters/fetch.js"() {
48184
48928
  init_platform();
48185
48929
  init_utils7();
48186
48930
  init_AxiosError();
@@ -48190,13 +48934,11 @@ var init_fetch = __esm({
48190
48934
  init_progressEventReducer();
48191
48935
  init_resolveConfig();
48192
48936
  init_settle();
48937
+ init_estimateDataURLDecodedBytes();
48938
+ init_data();
48939
+ init_sanitizeHeaderValue();
48193
48940
  DEFAULT_CHUNK_SIZE = 64 * 1024;
48194
48941
  ({ isFunction: isFunction2 } = utils_default);
48195
- globalFetchAPI = (({ Request: Request3, Response: Response3 }) => ({
48196
- Request: Request3,
48197
- Response: Response3
48198
- }))(utils_default.global);
48199
- ({ ReadableStream: ReadableStream2, TextEncoder: TextEncoder2 } = utils_default.global);
48200
48942
  test = (fn, ...args) => {
48201
48943
  try {
48202
48944
  return !!fn(...args);
@@ -48205,11 +48947,16 @@ var init_fetch = __esm({
48205
48947
  }
48206
48948
  };
48207
48949
  factory = (env) => {
48950
+ const globalObject = utils_default.global !== void 0 && utils_default.global !== null ? utils_default.global : globalThis;
48951
+ const { ReadableStream: ReadableStream2, TextEncoder: TextEncoder2 } = globalObject;
48208
48952
  env = utils_default.merge.call(
48209
48953
  {
48210
48954
  skipUndefined: true
48211
48955
  },
48212
- globalFetchAPI,
48956
+ {
48957
+ Request: globalObject.Request,
48958
+ Response: globalObject.Response
48959
+ },
48213
48960
  env
48214
48961
  );
48215
48962
  const { fetch: envFetch, Request: Request3, Response: Response3 } = env;
@@ -48297,8 +49044,12 @@ var init_fetch = __esm({
48297
49044
  responseType,
48298
49045
  headers,
48299
49046
  withCredentials = "same-origin",
48300
- fetchOptions
49047
+ fetchOptions,
49048
+ maxContentLength,
49049
+ maxBodyLength
48301
49050
  } = resolveConfig_default(config4);
49051
+ const hasMaxContentLength = utils_default.isNumber(maxContentLength) && maxContentLength > -1;
49052
+ const hasMaxBodyLength = utils_default.isNumber(maxBodyLength) && maxBodyLength > -1;
48302
49053
  let _fetch2 = envFetch || fetch;
48303
49054
  responseType = responseType ? (responseType + "").toLowerCase() : "text";
48304
49055
  let composedSignal = composeSignals_default(
@@ -48311,6 +49062,28 @@ var init_fetch = __esm({
48311
49062
  });
48312
49063
  let requestContentLength;
48313
49064
  try {
49065
+ if (hasMaxContentLength && typeof url3 === "string" && url3.startsWith("data:")) {
49066
+ const estimated = estimateDataURLDecodedBytes(url3);
49067
+ if (estimated > maxContentLength) {
49068
+ throw new AxiosError_default(
49069
+ "maxContentLength size of " + maxContentLength + " exceeded",
49070
+ AxiosError_default.ERR_BAD_RESPONSE,
49071
+ config4,
49072
+ request
49073
+ );
49074
+ }
49075
+ }
49076
+ if (hasMaxBodyLength && method !== "get" && method !== "head") {
49077
+ const outboundLength = await resolveBodyLength(headers, data);
49078
+ if (typeof outboundLength === "number" && isFinite(outboundLength) && outboundLength > maxBodyLength) {
49079
+ throw new AxiosError_default(
49080
+ "Request body larger than maxBodyLength limit",
49081
+ AxiosError_default.ERR_BAD_REQUEST,
49082
+ config4,
49083
+ request
49084
+ );
49085
+ }
49086
+ }
48314
49087
  if (onUploadProgress && supportsRequestStream && method !== "get" && method !== "head" && (requestContentLength = await resolveBodyLength(headers, data)) !== 0) {
48315
49088
  let _request = new Request3(url3, {
48316
49089
  method: "POST",
@@ -48339,19 +49112,31 @@ var init_fetch = __esm({
48339
49112
  headers.delete("content-type");
48340
49113
  }
48341
49114
  }
49115
+ headers.set("User-Agent", "axios/" + VERSION, false);
48342
49116
  const resolvedOptions = {
48343
49117
  ...fetchOptions,
48344
49118
  signal: composedSignal,
48345
49119
  method: method.toUpperCase(),
48346
- headers: headers.normalize().toJSON(),
49120
+ headers: toByteStringHeaderObject(headers.normalize()),
48347
49121
  body: data,
48348
49122
  duplex: "half",
48349
49123
  credentials: isCredentialsSupported ? withCredentials : void 0
48350
49124
  };
48351
49125
  request = isRequestSupported && new Request3(url3, resolvedOptions);
48352
49126
  let response = await (isRequestSupported ? _fetch2(request, fetchOptions) : _fetch2(url3, resolvedOptions));
49127
+ if (hasMaxContentLength) {
49128
+ const declaredLength = utils_default.toFiniteNumber(response.headers.get("content-length"));
49129
+ if (declaredLength != null && declaredLength > maxContentLength) {
49130
+ throw new AxiosError_default(
49131
+ "maxContentLength size of " + maxContentLength + " exceeded",
49132
+ AxiosError_default.ERR_BAD_RESPONSE,
49133
+ config4,
49134
+ request
49135
+ );
49136
+ }
49137
+ }
48353
49138
  const isStreamResponse = supportsResponseStream && (responseType === "stream" || responseType === "response");
48354
- if (supportsResponseStream && (onDownloadProgress || isStreamResponse && unsubscribe)) {
49139
+ if (supportsResponseStream && response.body && (onDownloadProgress || hasMaxContentLength || isStreamResponse && unsubscribe)) {
48355
49140
  const options = {};
48356
49141
  ["status", "statusText", "headers"].forEach((prop) => {
48357
49142
  options[prop] = response[prop];
@@ -48361,8 +49146,23 @@ var init_fetch = __esm({
48361
49146
  responseContentLength,
48362
49147
  progressEventReducer(asyncDecorator(onDownloadProgress), true)
48363
49148
  ) || [];
49149
+ let bytesRead = 0;
49150
+ const onChunkProgress = (loadedBytes) => {
49151
+ if (hasMaxContentLength) {
49152
+ bytesRead = loadedBytes;
49153
+ if (bytesRead > maxContentLength) {
49154
+ throw new AxiosError_default(
49155
+ "maxContentLength size of " + maxContentLength + " exceeded",
49156
+ AxiosError_default.ERR_BAD_RESPONSE,
49157
+ config4,
49158
+ request
49159
+ );
49160
+ }
49161
+ }
49162
+ onProgress && onProgress(loadedBytes);
49163
+ };
48364
49164
  response = new Response3(
48365
- trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => {
49165
+ trackStream(response.body, DEFAULT_CHUNK_SIZE, onChunkProgress, () => {
48366
49166
  flush && flush();
48367
49167
  unsubscribe && unsubscribe();
48368
49168
  }),
@@ -48374,6 +49174,26 @@ var init_fetch = __esm({
48374
49174
  response,
48375
49175
  config4
48376
49176
  );
49177
+ if (hasMaxContentLength && !supportsResponseStream && !isStreamResponse) {
49178
+ let materializedSize;
49179
+ if (responseData != null) {
49180
+ if (typeof responseData.byteLength === "number") {
49181
+ materializedSize = responseData.byteLength;
49182
+ } else if (typeof responseData.size === "number") {
49183
+ materializedSize = responseData.size;
49184
+ } else if (typeof responseData === "string") {
49185
+ materializedSize = typeof TextEncoder2 === "function" ? new TextEncoder2().encode(responseData).byteLength : responseData.length;
49186
+ }
49187
+ }
49188
+ if (typeof materializedSize === "number" && materializedSize > maxContentLength) {
49189
+ throw new AxiosError_default(
49190
+ "maxContentLength size of " + maxContentLength + " exceeded",
49191
+ AxiosError_default.ERR_BAD_RESPONSE,
49192
+ config4,
49193
+ request
49194
+ );
49195
+ }
49196
+ }
48377
49197
  !isStreamResponse && unsubscribe && unsubscribe();
48378
49198
  return await new Promise((resolve4, reject) => {
48379
49199
  settle(resolve4, reject, {
@@ -48387,6 +49207,13 @@ var init_fetch = __esm({
48387
49207
  });
48388
49208
  } catch (err) {
48389
49209
  unsubscribe && unsubscribe();
49210
+ if (composedSignal && composedSignal.aborted && composedSignal.reason instanceof AxiosError_default) {
49211
+ const canceledError = composedSignal.reason;
49212
+ canceledError.config = config4;
49213
+ request && (canceledError.request = request);
49214
+ err !== canceledError && (canceledError.cause = err);
49215
+ throw canceledError;
49216
+ }
48390
49217
  if (err && err.name === "TypeError" && /Load failed|fetch/i.test(err.message)) {
48391
49218
  throw Object.assign(
48392
49219
  new AxiosError_default(
@@ -48460,7 +49287,7 @@ var renderReason;
48460
49287
  var isResolvedHandle;
48461
49288
  var adapters_default;
48462
49289
  var init_adapters = __esm({
48463
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/adapters/adapters.js"() {
49290
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/adapters/adapters.js"() {
48464
49291
  init_utils7();
48465
49292
  init_http();
48466
49293
  init_xhr();
@@ -48476,10 +49303,10 @@ var init_adapters = __esm({
48476
49303
  utils_default.forEach(knownAdapters, (fn, value) => {
48477
49304
  if (fn) {
48478
49305
  try {
48479
- Object.defineProperty(fn, "name", { value });
49306
+ Object.defineProperty(fn, "name", { __proto__: null, value });
48480
49307
  } catch (e) {
48481
49308
  }
48482
- Object.defineProperty(fn, "adapterName", { value });
49309
+ Object.defineProperty(fn, "adapterName", { __proto__: null, value });
48483
49310
  }
48484
49311
  });
48485
49312
  renderReason = (reason) => `- ${reason}`;
@@ -48517,7 +49344,12 @@ function dispatchRequest(config4) {
48517
49344
  return adapter2(config4).then(
48518
49345
  function onAdapterResolution(response) {
48519
49346
  throwIfCancellationRequested(config4);
48520
- response.data = transformData.call(config4, config4.transformResponse, response);
49347
+ config4.response = response;
49348
+ try {
49349
+ response.data = transformData.call(config4, config4.transformResponse, response);
49350
+ } finally {
49351
+ delete config4.response;
49352
+ }
48521
49353
  response.headers = AxiosHeaders_default.from(response.headers);
48522
49354
  return response;
48523
49355
  },
@@ -48525,11 +49357,16 @@ function dispatchRequest(config4) {
48525
49357
  if (!isCancel(reason)) {
48526
49358
  throwIfCancellationRequested(config4);
48527
49359
  if (reason && reason.response) {
48528
- reason.response.data = transformData.call(
48529
- config4,
48530
- config4.transformResponse,
48531
- reason.response
48532
- );
49360
+ config4.response = reason.response;
49361
+ try {
49362
+ reason.response.data = transformData.call(
49363
+ config4,
49364
+ config4.transformResponse,
49365
+ reason.response
49366
+ );
49367
+ } finally {
49368
+ delete config4.response;
49369
+ }
48533
49370
  reason.response.headers = AxiosHeaders_default.from(reason.response.headers);
48534
49371
  }
48535
49372
  }
@@ -48538,7 +49375,7 @@ function dispatchRequest(config4) {
48538
49375
  );
48539
49376
  }
48540
49377
  var init_dispatchRequest = __esm({
48541
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/core/dispatchRequest.js"() {
49378
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/core/dispatchRequest.js"() {
48542
49379
  init_transformData();
48543
49380
  init_isCancel();
48544
49381
  init_defaults();
@@ -48576,7 +49413,7 @@ var validators;
48576
49413
  var deprecatedWarnings;
48577
49414
  var validator_default;
48578
49415
  var init_validator = __esm({
48579
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/validator.js"() {
49416
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/validator.js"() {
48580
49417
  init_data();
48581
49418
  init_AxiosError();
48582
49419
  validators = {};
@@ -48625,7 +49462,7 @@ var validators2;
48625
49462
  var Axios;
48626
49463
  var Axios_default;
48627
49464
  var init_Axios = __esm({
48628
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/core/Axios.js"() {
49465
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/core/Axios.js"() {
48629
49466
  init_utils7();
48630
49467
  init_buildURL();
48631
49468
  init_InterceptorManager();
@@ -48736,7 +49573,7 @@ var init_Axios = __esm({
48736
49573
  );
48737
49574
  config4.method = (config4.method || this.defaults.method || "get").toLowerCase();
48738
49575
  let contextHeaders = headers && utils_default.merge(headers.common, headers[config4.method]);
48739
- headers && utils_default.forEach(["delete", "get", "head", "post", "put", "patch", "common"], (method) => {
49576
+ headers && utils_default.forEach(["delete", "get", "head", "post", "put", "patch", "query", "common"], (method) => {
48740
49577
  delete headers[method];
48741
49578
  });
48742
49579
  config4.headers = AxiosHeaders_default.concat(contextHeaders, headers);
@@ -48814,7 +49651,7 @@ var init_Axios = __esm({
48814
49651
  );
48815
49652
  };
48816
49653
  });
48817
- utils_default.forEach(["post", "put", "patch"], function forEachMethodWithData(method) {
49654
+ utils_default.forEach(["post", "put", "patch", "query"], function forEachMethodWithData(method) {
48818
49655
  function generateHTTPMethod(isForm) {
48819
49656
  return function httpMethod(url3, data, config4) {
48820
49657
  return this.request(
@@ -48830,7 +49667,9 @@ var init_Axios = __esm({
48830
49667
  };
48831
49668
  }
48832
49669
  Axios.prototype[method] = generateHTTPMethod();
48833
- Axios.prototype[method + "Form"] = generateHTTPMethod(true);
49670
+ if (method !== "query") {
49671
+ Axios.prototype[method + "Form"] = generateHTTPMethod(true);
49672
+ }
48834
49673
  });
48835
49674
  Axios_default = Axios;
48836
49675
  }
@@ -48838,7 +49677,7 @@ var init_Axios = __esm({
48838
49677
  var CancelToken;
48839
49678
  var CancelToken_default;
48840
49679
  var init_CancelToken = __esm({
48841
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/cancel/CancelToken.js"() {
49680
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/cancel/CancelToken.js"() {
48842
49681
  init_CanceledError();
48843
49682
  CancelToken = class _CancelToken {
48844
49683
  constructor(executor) {
@@ -48944,21 +49783,21 @@ function spread(callback) {
48944
49783
  };
48945
49784
  }
48946
49785
  var init_spread = __esm({
48947
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/spread.js"() {
49786
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/spread.js"() {
48948
49787
  }
48949
49788
  });
48950
49789
  function isAxiosError(payload) {
48951
49790
  return utils_default.isObject(payload) && payload.isAxiosError === true;
48952
49791
  }
48953
49792
  var init_isAxiosError = __esm({
48954
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/isAxiosError.js"() {
49793
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/isAxiosError.js"() {
48955
49794
  init_utils7();
48956
49795
  }
48957
49796
  });
48958
49797
  var HttpStatusCode;
48959
49798
  var HttpStatusCode_default;
48960
49799
  var init_HttpStatusCode = __esm({
48961
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/helpers/HttpStatusCode.js"() {
49800
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/helpers/HttpStatusCode.js"() {
48962
49801
  HttpStatusCode = {
48963
49802
  Continue: 100,
48964
49803
  SwitchingProtocols: 101,
@@ -49041,7 +49880,7 @@ function createInstance(defaultConfig) {
49041
49880
  const instance = bind(Axios_default.prototype.request, context);
49042
49881
  utils_default.extend(instance, Axios_default.prototype, context, { allOwnKeys: true });
49043
49882
  utils_default.extend(instance, context, null, { allOwnKeys: true });
49044
- instance.create = function create6(instanceConfig) {
49883
+ instance.create = function create7(instanceConfig) {
49045
49884
  return createInstance(mergeConfig(defaultConfig, instanceConfig));
49046
49885
  };
49047
49886
  return instance;
@@ -49049,7 +49888,7 @@ function createInstance(defaultConfig) {
49049
49888
  var axios;
49050
49889
  var axios_default;
49051
49890
  var init_axios = __esm({
49052
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/lib/axios.js"() {
49891
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/lib/axios.js"() {
49053
49892
  init_utils7();
49054
49893
  init_bind();
49055
49894
  init_Axios();
@@ -49106,8 +49945,9 @@ var HttpStatusCode2;
49106
49945
  var formToJSON;
49107
49946
  var getAdapter2;
49108
49947
  var mergeConfig2;
49948
+ var create;
49109
49949
  var init_axios2 = __esm({
49110
- "../../node_modules/.pnpm/axios@1.15.2/node_modules/axios/index.js"() {
49950
+ "../../node_modules/.pnpm/axios@1.16.1/node_modules/axios/index.js"() {
49111
49951
  init_axios();
49112
49952
  ({
49113
49953
  Axios: Axios2,
@@ -49125,7 +49965,8 @@ var init_axios2 = __esm({
49125
49965
  HttpStatusCode: HttpStatusCode2,
49126
49966
  formToJSON,
49127
49967
  getAdapter: getAdapter2,
49128
- mergeConfig: mergeConfig2
49968
+ mergeConfig: mergeConfig2,
49969
+ create
49129
49970
  } = axios_default);
49130
49971
  }
49131
49972
  });
@@ -49228,7 +50069,7 @@ var y;
49228
50069
  var B;
49229
50070
  var te;
49230
50071
  var init_lib = __esm({
49231
- "../../node_modules/.pnpm/@zodios+core@10.9.6_axios@1.15.2_zod@3.25.76/node_modules/@zodios/core/lib/index.mjs"() {
50072
+ "../../node_modules/.pnpm/@zodios+core@10.9.6_axios@1.16.1_zod@3.25.76/node_modules/@zodios/core/lib/index.mjs"() {
49232
50073
  init_axios2();
49233
50074
  M = /:([a-zA-Z_][a-zA-Z0-9_]*)/g;
49234
50075
  u = class extends Error {
@@ -49405,7 +50246,7 @@ var LatestPublisherStakeCapsUpdateDataResponse;
49405
50246
  var schemas;
49406
50247
  var endpoints;
49407
50248
  var init_zodSchemas = __esm({
49408
- "../../node_modules/.pnpm/@pythnetwork+hermes-client@3.1.0_axios@1.15.2/node_modules/@pythnetwork/hermes-client/dist/esm/zodSchemas.mjs"() {
50249
+ "../../node_modules/.pnpm/@pythnetwork+hermes-client@3.1.0_axios@1.16.1/node_modules/@pythnetwork/hermes-client/dist/esm/zodSchemas.mjs"() {
49409
50250
  init_lib();
49410
50251
  init_zod();
49411
50252
  AssetType = external_exports.enum([
@@ -49681,7 +50522,7 @@ var DEFAULT_TIMEOUT;
49681
50522
  var DEFAULT_HTTP_RETRIES;
49682
50523
  var HermesClient;
49683
50524
  var init_hermes_client = __esm({
49684
- "../../node_modules/.pnpm/@pythnetwork+hermes-client@3.1.0_axios@1.15.2/node_modules/@pythnetwork/hermes-client/dist/esm/hermes-client.mjs"() {
50525
+ "../../node_modules/.pnpm/@pythnetwork+hermes-client@3.1.0_axios@1.16.1/node_modules/@pythnetwork/hermes-client/dist/esm/hermes-client.mjs"() {
49685
50526
  init_dist6();
49686
50527
  init_utils6();
49687
50528
  init_zodSchemas();
@@ -49887,7 +50728,7 @@ var init_hermes_client = __esm({
49887
50728
  }
49888
50729
  });
49889
50730
  var init_esm = __esm({
49890
- "../../node_modules/.pnpm/@pythnetwork+hermes-client@3.1.0_axios@1.15.2/node_modules/@pythnetwork/hermes-client/dist/esm/index.mjs"() {
50731
+ "../../node_modules/.pnpm/@pythnetwork+hermes-client@3.1.0_axios@1.16.1/node_modules/@pythnetwork/hermes-client/dist/esm/index.mjs"() {
49891
50732
  init_hermes_client();
49892
50733
  }
49893
50734
  });
@@ -51804,7 +52645,7 @@ var DEFAULT_ENDPOINT;
51804
52645
  var _AggregatorClient;
51805
52646
  var AggregatorClient;
51806
52647
  var init_dist7 = __esm({
51807
- "../../node_modules/.pnpm/@cetusprotocol+aggregator-sdk@1.4.8_axios@1.15.2_typescript@5.9.3/node_modules/@cetusprotocol/aggregator-sdk/dist/index.js"() {
52648
+ "../../node_modules/.pnpm/@cetusprotocol+aggregator-sdk@1.4.8_axios@1.16.1_typescript@5.9.3/node_modules/@cetusprotocol/aggregator-sdk/dist/index.js"() {
51808
52649
  init_transactions();
51809
52650
  import_json_bigint = __toESM(require_json_bigint());
51810
52651
  init_utils3();
@@ -65666,8 +66507,8 @@ var init_weierstrass = __esm({
65666
66507
  }
65667
66508
  });
65668
66509
  function createCurve(curveDef, defHash) {
65669
- const create6 = (hash7) => weierstrass({ ...curveDef, hash: hash7 });
65670
- return { ...create6(defHash), create: create6 };
66510
+ const create7 = (hash7) => weierstrass({ ...curveDef, hash: hash7 });
66511
+ return { ...create7(defHash), create: create7 };
65671
66512
  }
65672
66513
  var init_shortw_utils = __esm({
65673
66514
  "../../node_modules/.pnpm/@noble+curves@1.9.7/node_modules/@noble/curves/esm/_shortw_utils.js"() {
@@ -69218,7 +70059,7 @@ var init_abiParameters = __esm({
69218
70059
  sizeOfOffset = 32;
69219
70060
  }
69220
70061
  });
69221
- function create(bytes, { recursiveReadLimit = 8192 } = {}) {
70062
+ function create2(bytes, { recursiveReadLimit = 8192 } = {}) {
69222
70063
  const cursor = Object.create(staticCursor);
69223
70064
  cursor.bytes = bytes;
69224
70065
  cursor.dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
@@ -69445,7 +70286,7 @@ __export(AbiParameters_exports, {
69445
70286
  function decode(parameters, data, options = {}) {
69446
70287
  const { as = "Array", checksumAddress: checksumAddress2 = false } = options;
69447
70288
  const bytes = typeof data === "string" ? fromHex2(data) : data;
69448
- const cursor = create(bytes);
70289
+ const cursor = create2(bytes);
69449
70290
  if (size(bytes) === 0 && parameters.length > 0)
69450
70291
  throw new ZeroDataError();
69451
70292
  if (size(bytes) && size(bytes) < 32)
@@ -71229,8 +72070,8 @@ function getHash(hash7) {
71229
72070
  };
71230
72071
  }
71231
72072
  function createCurve2(curveDef, defHash) {
71232
- const create6 = (hash7) => weierstrass2({ ...curveDef, ...getHash(hash7) });
71233
- return { ...create6(defHash), create: create6 };
72073
+ const create7 = (hash7) => weierstrass2({ ...curveDef, ...getHash(hash7) });
72074
+ return { ...create7(defHash), create: create7 };
71234
72075
  }
71235
72076
  var init_shortw_utils2 = __esm({
71236
72077
  "../../node_modules/.pnpm/@noble+curves@1.9.1/node_modules/@noble/curves/esm/_shortw_utils.js"() {
@@ -99217,7 +100058,7 @@ var init_abiParameters2 = __esm({
99217
100058
  sizeOfOffset3 = 32;
99218
100059
  }
99219
100060
  });
99220
- function create2(bytes, { recursiveReadLimit = 8192 } = {}) {
100061
+ function create3(bytes, { recursiveReadLimit = 8192 } = {}) {
99221
100062
  const cursor = Object.create(staticCursor3);
99222
100063
  cursor.bytes = bytes;
99223
100064
  cursor.dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
@@ -99429,7 +100270,7 @@ var init_cursor4 = __esm({
99429
100270
  function decode3(parameters, data, options = {}) {
99430
100271
  const { as = "Array", checksumAddress: checksumAddress2 = false } = options;
99431
100272
  const bytes = typeof data === "string" ? fromHex6(data) : data;
99432
- const cursor = create2(bytes);
100273
+ const cursor = create3(bytes);
99433
100274
  if (size4(bytes) === 0 && parameters.length > 0)
99434
100275
  throw new ZeroDataError2();
99435
100276
  if (size4(bytes) && size4(bytes) < 32)
@@ -99658,7 +100499,7 @@ function to(value, to2) {
99658
100499
  }
99659
100500
  return value;
99660
100501
  })();
99661
- const cursor = create2(bytes, {
100502
+ const cursor = create3(bytes, {
99662
100503
  recursiveReadLimit: Number.POSITIVE_INFINITY
99663
100504
  });
99664
100505
  const result = decodeRlpCursor(cursor, to_);
@@ -99703,7 +100544,7 @@ function readList2(cursor, length, to2) {
99703
100544
  function from18(value, options) {
99704
100545
  const { as } = options;
99705
100546
  const encodable = getEncodable3(value);
99706
- const cursor = create2(new Uint8Array(encodable.length));
100547
+ const cursor = create3(new Uint8Array(encodable.length));
99707
100548
  encodable.encode(cursor);
99708
100549
  if (as === "Hex")
99709
100550
  return fromBytes5(cursor.bytes);
@@ -107121,7 +107962,7 @@ var init_nonce = __esm({
107121
107962
  });
107122
107963
  var policy_exports = {};
107123
107964
  __export(policy_exports, {
107124
- create: () => create3,
107965
+ create: () => create4,
107125
107966
  createSync: () => createSync,
107126
107967
  getData: () => getData,
107127
107968
  isAuthorized: () => isAuthorized,
@@ -107136,16 +107977,16 @@ __export(policy_exports, {
107136
107977
  watchCreate: () => watchCreate,
107137
107978
  watchWhitelistUpdated: () => watchWhitelistUpdated
107138
107979
  });
107139
- async function create3(client, parameters) {
107140
- return create3.inner(writeContract, client, parameters);
107980
+ async function create4(client, parameters) {
107981
+ return create4.inner(writeContract, client, parameters);
107141
107982
  }
107142
107983
  async function createSync(client, parameters) {
107143
107984
  const { throwOnReceiptRevert = true, ...rest } = parameters;
107144
- const receipt = await create3.inner(writeContractSync, client, {
107985
+ const receipt = await create4.inner(writeContractSync, client, {
107145
107986
  ...rest,
107146
107987
  throwOnReceiptRevert
107147
107988
  });
107148
- const { args } = create3.extractEvent(receipt.logs);
107989
+ const { args } = create4.extractEvent(receipt.logs);
107149
107990
  return {
107150
107991
  ...args,
107151
107992
  receipt
@@ -107289,13 +108130,13 @@ var init_policy = __esm({
107289
108130
  whitelist: 0,
107290
108131
  blacklist: 1
107291
108132
  };
107292
- (function(create6) {
108133
+ (function(create7) {
107293
108134
  async function inner(action, client, parameters) {
107294
108135
  const { account = client.account, addresses, chain: chain2 = client.chain, type: type2, ...rest } = parameters;
107295
108136
  if (!account)
107296
108137
  throw new Error("`account` is required");
107297
108138
  const admin = parseAccount(account).address;
107298
- const call3 = create6.call({ admin, type: type2, addresses });
108139
+ const call3 = create7.call({ admin, type: type2, addresses });
107299
108140
  return action(client, {
107300
108141
  ...rest,
107301
108142
  account,
@@ -107303,7 +108144,7 @@ var init_policy = __esm({
107303
108144
  ...call3
107304
108145
  });
107305
108146
  }
107306
- create6.inner = inner;
108147
+ create7.inner = inner;
107307
108148
  function call2(args) {
107308
108149
  const { admin, type: type2, addresses } = args;
107309
108150
  const config4 = (() => {
@@ -107323,7 +108164,7 @@ var init_policy = __esm({
107323
108164
  ...config4
107324
108165
  });
107325
108166
  }
107326
- create6.call = call2;
108167
+ create7.call = call2;
107327
108168
  function extractEvent(logs) {
107328
108169
  const [log3] = parseEventLogs({
107329
108170
  abi: tip403Registry,
@@ -107335,8 +108176,8 @@ var init_policy = __esm({
107335
108176
  throw new Error("`PolicyCreated` event not found.");
107336
108177
  return log3;
107337
108178
  }
107338
- create6.extractEvent = extractEvent;
107339
- })(create3 || (create3 = {}));
108179
+ create7.extractEvent = extractEvent;
108180
+ })(create4 || (create4 = {}));
107340
108181
  (function(setAdmin2) {
107341
108182
  async function inner(action, client, parameters) {
107342
108183
  const { policyId, admin, ...rest } = parameters;
@@ -107717,7 +108558,7 @@ __export(token_exports, {
107717
108558
  burnSync: () => burnSync2,
107718
108559
  changeTransferPolicy: () => changeTransferPolicy,
107719
108560
  changeTransferPolicySync: () => changeTransferPolicySync,
107720
- create: () => create4,
108561
+ create: () => create5,
107721
108562
  createSync: () => createSync2,
107722
108563
  getAllowance: () => getAllowance,
107723
108564
  getBalance: () => getBalance2,
@@ -107813,16 +108654,16 @@ async function changeTransferPolicySync(client, parameters) {
107813
108654
  receipt
107814
108655
  };
107815
108656
  }
107816
- async function create4(client, parameters) {
107817
- return create4.inner(writeContract, client, parameters);
108657
+ async function create5(client, parameters) {
108658
+ return create5.inner(writeContract, client, parameters);
107818
108659
  }
107819
108660
  async function createSync2(client, parameters) {
107820
108661
  const { throwOnReceiptRevert = true, ...rest } = parameters;
107821
- const receipt = await create4.inner(writeContractSync, client, {
108662
+ const receipt = await create5.inner(writeContractSync, client, {
107822
108663
  ...rest,
107823
108664
  throwOnReceiptRevert
107824
108665
  });
107825
- const { args } = create4.extractEvent(receipt.logs);
108666
+ const { args } = create5.extractEvent(receipt.logs);
107826
108667
  const tokenId = TokenId_exports.fromAddress(args.token);
107827
108668
  return {
107828
108669
  ...args,
@@ -108402,13 +109243,13 @@ var init_token = __esm({
108402
109243
  }
108403
109244
  changeTransferPolicy2.extractEvent = extractEvent;
108404
109245
  })(changeTransferPolicy || (changeTransferPolicy = {}));
108405
- (function(create6) {
109246
+ (function(create7) {
108406
109247
  async function inner(action, client, parameters) {
108407
109248
  const { account = client.account, admin: admin_ = client.account, chain: chain2 = client.chain, ...rest } = parameters;
108408
109249
  const admin = admin_ ? parseAccount(admin_) : void 0;
108409
109250
  if (!admin)
108410
109251
  throw new Error("admin is required.");
108411
- const call3 = create6.call({ ...rest, admin: admin.address });
109252
+ const call3 = create7.call({ ...rest, admin: admin.address });
108412
109253
  return await action(client, {
108413
109254
  ...parameters,
108414
109255
  account,
@@ -108416,7 +109257,7 @@ var init_token = __esm({
108416
109257
  ...call3
108417
109258
  });
108418
109259
  }
108419
- create6.inner = inner;
109260
+ create7.inner = inner;
108420
109261
  function call2(args) {
108421
109262
  const { name, symbol: symbol2, currency: currency2, quoteToken = pathUsd, admin, salt = random5(32) } = args;
108422
109263
  return defineCall({
@@ -108433,7 +109274,7 @@ var init_token = __esm({
108433
109274
  functionName: "createToken"
108434
109275
  });
108435
109276
  }
108436
- create6.call = call2;
109277
+ create7.call = call2;
108437
109278
  function extractEvent(logs) {
108438
109279
  const [log3] = parseEventLogs({
108439
109280
  abi: tip20Factory,
@@ -108445,8 +109286,8 @@ var init_token = __esm({
108445
109286
  throw new Error("`TokenCreated` event not found.");
108446
109287
  return log3;
108447
109288
  }
108448
- create6.extractEvent = extractEvent;
108449
- })(create4 || (create4 = {}));
109289
+ create7.extractEvent = extractEvent;
109290
+ })(create5 || (create5 = {}));
108450
109291
  (function(getAllowance2) {
108451
109292
  function call2(args) {
108452
109293
  const { account, spender, token } = args;
@@ -111905,10 +112746,10 @@ var init_Transport2 = __esm({
111905
112746
  });
111906
112747
  var Mppx_exports = {};
111907
112748
  __export(Mppx_exports, {
111908
- create: () => create5,
112749
+ create: () => create6,
111909
112750
  restore: () => restore2
111910
112751
  });
111911
- function create5(config4) {
112752
+ function create6(config4) {
111912
112753
  const { onChallenge, polyfill: polyfill2 = true, transport = http4() } = config4;
111913
112754
  const rawFetch = config4.fetch ?? globalThis.fetch;
111914
112755
  const methods = config4.methods.flat();
@@ -126876,7 +127717,7 @@ ${pckCertChain}`;
126876
127717
  };
126877
127718
  }
126878
127719
  });
126879
- var require_src2 = __commonJS({
127720
+ var require_src3 = __commonJS({
126880
127721
  "../../node_modules/.pnpm/@phala+dcap-qvl@0.5.2/node_modules/@phala/dcap-qvl/src/index.js"(exports$1, module) {
126881
127722
  var { Quote } = require_quote();
126882
127723
  var { verify: verify13, QuoteVerifier, VerifiedReport } = require_verify();
@@ -144373,7 +145214,7 @@ async function verifyTdxQuote(base, model, receiptWorkloadId) {
144373
145214
  };
144374
145215
  }
144375
145216
  try {
144376
- const dcap = await Promise.resolve().then(() => __toESM(require_src2(), 1));
145217
+ const dcap = await Promise.resolve().then(() => __toESM(require_src3(), 1));
144377
145218
  const getCollateralAndVerify = dcap.getCollateralAndVerify ?? dcap.default?.getCollateralAndVerify;
144378
145219
  if (typeof getCollateralAndVerify !== "function") {
144379
145220
  return {
@@ -146282,7 +147123,7 @@ function registerChatTools(server) {
146282
147123
  var cachedSkills = null;
146283
147124
  function getBakedSkills() {
146284
147125
  if (cachedSkills) return cachedSkills;
146285
- const raw = '[{"name":"deepbook","description":"Read live market data from DeepBook, Sui\'s on-chain central limit order book \u2014 pools, tickers, order books, candles, trades \u2014 over a free public REST indexer. Use for Sui price checks, market depth, volume, or OHLCV questions. Read-only.","body":"# DeepBook: Market reads\\n\\n## Purpose\\n\\nDeepBook v3 is Sui\'s shared order book. Mysten runs a free public indexer \u2014 no key, no wallet:\\n\\n```text\\nhttps://deepbook-indexer.mainnet.mystenlabs.com\\n```\\n\\nPair names are `BASE_QUOTE` (e.g. `SUI_USDC`, `DEEP_USDC`, `WAL_USDC`). Get the live list from `/get_pools`.\\n\\n## Rules\\n\\n1. **Discover pairs first.** Pool names are exact \u2014 call `/get_pools` or `/ticker` before assuming a pair exists.\\n2. **Prices come pre-scaled.** Ticker/orderbook/candle prices are already in human units \u2014 don\'t re-divide by decimals.\\n3. **Check `isFrozen`.** A ticker entry with `isFrozen: 1` is an inactive pool \u2014 don\'t quote it as a live price.\\n4. **This is one venue.** DeepBook depth \u2260 all of Sui liquidity. For a best-execution swap across 20+ DEXs, use the `t2000-swap` skill; use DeepBook reads for order-book-grade data.\\n\\n## Endpoints\\n\\n```bash\\nB=https://deepbook-indexer.mainnet.mystenlabs.com\\n\\ncurl -s \\"$B/get_pools\\" # every pool + assets, decimals, tick/lot sizes\\ncurl -s \\"$B/ticker\\" # all pairs: last_price, 24h volume, isFrozen\\ncurl -s \\"$B/summary\\" # 24h stats per pair (bid/ask, high/low, % change)\\ncurl -s \\"$B/orderbook/SUI_USDC?level=2&depth=10\\" # live bids/asks (level 1 = top of book)\\ncurl -s \\"$B/ohclv/SUI_USDC?interval=1h&limit=24\\" # candles: [ts_ms, open, high, close, low, volume]\\ncurl -s \\"$B/trades/SUI_USDC?limit=5\\" # recent fills (price, size, side, tx digest)\\ncurl -s \\"$B/historical_volume/SUI_USDC?start_time=<unix_s>&end_time=<unix_s>\\"\\n```\\n\\nVerified live examples:\\n\\n```bash\\ncurl -s \\"$B/orderbook/SUI_USDC?level=2&depth=4\\"\\n# {\\"bids\\":[[\\"0.73174\\",\\"240\\"],\u2026],\\"asks\\":[[\\"0.732\\",\\"1392.2\\"],\u2026],\\"timestamp\\":\\"1783734413301\\"}\\n\\ncurl -s \\"$B/ticker\\" | python3 -c \\"import json,sys; print(json.load(sys.stdin)[\'SUI_USDC\'])\\"\\n# {\'last_price\': 0.732\u2026, \'base_volume\': \u2026, \'quote_volume\': \u2026, \'isFrozen\': 0}\\n```\\n\\n## Answer patterns\\n\\n- **\\"What\'s SUI trading at?\\"** \u2192 `/ticker`, read `SUI_USDC.last_price`, quote the venue (\\"on DeepBook\\").\\n- **\\"How deep is the book?\\"** \u2192 `/orderbook/<pair>?level=2&depth=20`, sum bid/ask sizes near mid.\\n- **\\"Chart the last day\\"** \u2192 `/ohclv/<pair>?interval=1h&limit=24`. Note the field order in the name: o-h-**c-l**-v.\\n- **\\"Is volume real?\\"** \u2192 `/trades/<pair>` rows carry the Sui tx `digest` \u2014 every fill is verifiable on-chain (`https://suiscan.xyz/mainnet/tx/<digest>`).\\n\\n## Gotchas\\n\\n- The candle endpoint is spelled `ohclv` (not `ohlcv`) \u2014 and the array order matches: `[ts, open, high, close, low, volume]`.\\n- Timestamps: candle/orderbook are **milliseconds**; `historical_volume` params are **seconds**.\\n- Trading (placing orders) needs a BalanceManager + the DeepBook SDK \u2014 out of scope here; this skill is reads.\\n\\nLive docs: [docs.sui.io \u2192 DeepBookV3 Indexer](https://docs.sui.io/onchain-finance/deepbookv3/deepbookv3-indexer)."},{"name":"sui-grpc","description":"Read Sui chain state over gRPC \u2014 balances, objects, transactions, coin metadata, names. Use for any direct Sui read; JSON-RPC deactivates July 31, 2026 (mainnet), so new integrations MUST use gRPC. Read-only.","body":"# Sui: Read the chain over gRPC\\n\\n## Purpose\\n\\nThe canonical way to read Sui in 2026. One client covers balances, objects, transactions, metadata, and name service.\\n\\n> **JSON-RPC is being retired (mainnet: July 31, 2026).** `SuiClient` / `suix_*` / `sui_*` HTTP methods stop working on public fullnodes. Everything below is the replacement surface, verified against mainnet.\\n\\n## Setup\\n\\n```js\\nimport { SuiGrpcClient } from \'@mysten/sui/grpc\';\\n\\nconst client = new SuiGrpcClient({\\n baseUrl: \'https://fullnode.mainnet.sui.io\',\\n network: \'mainnet\',\\n});\\n```\\n\\n## The reads\\n\\n```js\\n// One coin balance (owner + coinType)\\nconst { balance } = await client.core.getBalance({\\n owner: \'0x\u2026\',\\n coinType: \'0x2::sui::SUI\',\\n});\\n// balance.balance = total, split into coinBalance + addressBalance (SIP-58)\\n\\n// Every balance an address holds\\nconst { balances } = await client.core.listBalances({ owner: \'0x\u2026\' });\\n\\n// Coin metadata (decimals, symbol) \u2014 never hardcode decimals\\nconst { coinMetadata } = await client.core.getCoinMetadata({\\n coinType: \'0xdba3\u2026::usdc::USDC\',\\n});\\n\\n// Objects an address owns\\nconst { objects, hasNextPage, cursor } = await client.core.listOwnedObjects({\\n owner: \'0x\u2026\',\\n limit: 50,\\n});\\n// each: { objectId, version, digest, type, owner, content }\\n\\n// One object / one transaction\\nconst obj = await client.core.getObject({ objectId: \'0x\u2026\' });\\nconst tx = await client.core.getTransaction({ digest: \'\u2026\' });\\n\\n// SuiNS\\nconst { record } = await client.nameService.lookupName({ name: \'agent-id.sui\' });\\n```\\n\\n## Rules\\n\\n1. **Amounts are strings/bigints in base units.** Scale by `coinMetadata.decimals` for display; never `parseFloat` raw chain values into math you\'ll transact on.\\n2. **A balance has two pots (SIP-58).** `coinBalance` (coin objects) + `addressBalance` (address-balance accumulator) sum to `balance` \u2014 report the total unless debugging transfers.\\n3. **Paginate.** `listOwnedObjects` / `listCoins` return `cursor` + `hasNextPage`; loop until done for full inventories.\\n4. **Don\'t write from this skill.** Building + signing transactions is wallet territory \u2014 use the t2000 Agent Wallet (`t2 send \xB7 swap \xB7 pay`) or `@t2000/sdk`, which run on this same gRPC surface.\\n\\n## Field-masked reads (advanced)\\n\\nLarge objects/transactions support read masks to fetch only what you need:\\n\\n```js\\nconst tx = await client.ledgerService.getTransaction({\\n digest: \'\u2026\',\\n readMask: { paths: [\'effects\', \'events\'] },\\n});\\n```\\n\\n## Gotchas\\n\\n- The gRPC client returns **BigInt** for u64s \u2014 `JSON.stringify` throws on them; convert with a replacer: `(k, v) => typeof v === \'bigint\' ? v.toString() : v`.\\n- `getBalance` takes `owner`, not `address` \u2014 a wrong key name errors as `missing owner`.\\n- Public fullnode gRPC is rate-limited like RPC was; batch via list endpoints instead of hammering singles."},{"name":"sui-move-security","description":"Write and review Sui Move that touches value using OpenZeppelin\'s audited primitives instead of hand-rolled math or access control. Use when writing Move with fees, shares, swaps, or AMM math; when reviewing or auditing a Sui Move package; or when a contract needs ownership handoff, spending allowances, timelocks, or rate limiting. Teaches the never-roll-your-own rules and where each OZ package applies.","body":"# Sui Move Security \u2014 OpenZeppelin Contracts for Sui\\n\\n## Purpose\\n\\nIn May 2025 a single flawed overflow check in a shared math library \u2014 a\\n`checked_shl`-class function that silently passed a value it should have\\nrejected \u2014 led to the Cetus exploit: ~$223M drained from the largest DEX on\\nSui, and a corrupted fixed-point intermediate that multiple downstream\\nprotocols depended on. The lesson is structural, not incidental: **value-path\\nmath and privileged-capability handling must come from audited primitives,\\nnever be hand-rolled.**\\n\\n[OpenZeppelin Contracts for Sui](https://docs.openzeppelin.com/contracts-sui)\\n(MIT) is that library. This skill is the map; the SSOT is upstream \u2014 start\\nfrom the machine-readable entry point when you need detail:\\n<https://raw.githubusercontent.com/OpenZeppelin/contracts-sui/main/llms.txt>\\n\\n## Hard rules (apply to every Move review and every new module)\\n\\n1. **Never write `(a * b) / c` manually.** The intermediate product overflows\\n even when the final result would fit. Use `mul_div` (widens internally,\\n returns `Option`). Power-of-two denominator (Q64.64 / tick math)? Use\\n `mul_shr` \u2014 the Cetus exploit lived in exactly this operation class.\\n2. **Rounding is a protocol decision, not a detail.** Every OZ divide/shift/\\n root takes an explicit `RoundingMode` \u2014 there is no default. Rule of\\n thumb: round **down** on protocol-to-user payouts (vault shares both\\n directions \u2014 the vault keeps the remainder), **up** only for conservative\\n upper bounds the protocol absorbs, `nearest()` for quotes/display. If a\\n deposit rounds up or a withdrawal rounds up, you built a drain loop.\\n3. **Handle the `Option` at the boundary.** Overflow-prone ops return\\n `Option<T>`: abort with a domain error (`.destroy_or!(abort EMathOverflow)`),\\n cap at a safe value, or propagate \u2014 but never `destroy_some()` blind.\\n4. **Never shift with `<<` / `>>` on value paths.** Move\'s native shifts\\n silently discard bits. `checked_shl` / `checked_shr` return `None` when\\n any non-zero bit would be lost.\\n5. **`(a + b) / 2` overflows near type max** \u2014 use `average(a, b, mode)`.\\n6. **Decimal conversions go through `decimal_scaling`** (`safe_upcast_balance`\\n / `safe_downcast_balance`) \u2014 never a hand-written `* 10^k`. Downcasts\\n truncate; if the remainder matters, capture it before the downcast.\\n7. **`u64` is the standard width** (Sui coin balances, timestamps, gas).\\n Reach for `u128`/`u256` only when the domain demands it; never use `u512`\\n directly (it exists for the library\'s internal widening).\\n8. **Privileged capabilities need transfer policies.** Raw\\n `transfer::transfer(admin_cap, new_owner)` is a one-shot, typo-fatal\\n handoff. Use `openzeppelin_access` (two-step approvals, time-locked\\n transfers); for delayed privileged ops, `openzeppelin_timelock`.\\n\\n## Install (Move.toml \u2014 MVR, pin stable releases)\\n\\n```toml\\n[dependencies]\\nopenzeppelin_math = { r.mvr = \\"@openzeppelin-move/integer-math\\" }\\nopenzeppelin_fp_math = { r.mvr = \\"@openzeppelin-move/fixed-point-math\\" }\\nopenzeppelin_access = { r.mvr = \\"@openzeppelin-move/access\\" }\\nopenzeppelin_utils = { r.mvr = \\"@openzeppelin-move/utils\\" }\\n```\\n\\nVerify with `sui move build`. Each package ships compilable examples under\\nits `examples/` dir \u2014 read them before wiring (composition recipes, not docs\\nprose).\\n\\n## The package map (which one for which job)\\n\\n| Need | Package (MVR) | Teaching |\\n| --- | --- | --- |\\n| Fees, shares, swap quotes, interest | `@openzeppelin-move/integer-math` | `mul_div`/`mul_shr`/`average` + explicit rounding + `Option` boundary |\\n| Prices, ratios, signed deltas | `@openzeppelin-move/fixed-point-math` | 9-decimal `UD30x9`/`SD29x9` on `u128` \u2014 same explicit-rounding philosophy |\\n| Ownership handoff of caps | `@openzeppelin-move/access` | two-step approvals, time-locked transfers \u2014 no one-shot cap sends |\\n| Throttling on-chain actions | `@openzeppelin-move/utils` | rate limiter: token bucket, fixed window, cooldown |\\n| Bounded delegated spending | `openzeppelin_allowance` (path dep) | capability-keyed budgets \u2014 owner keeps custody |\\n| Scheduled/locked releases | `openzeppelin_finance` / `openzeppelin_timelock` (path deps) | vesting curves \xB7 delayed-operation controller |\\n\\n## Canonical snippet (fee quote, from the OZ docs)\\n\\n```move\\nmodule my_sui_app::pricing;\\n\\nuse openzeppelin_math::{rounding, u64};\\n\\nconst EMathOverflow: u64 = 0;\\n\\npublic fun quote_with_fee(amount: u64): u64 {\\n u64::mul_div(amount, 1025u64, 1000u64, rounding::nearest())\\n .destroy_or!(abort EMathOverflow)\\n}\\n```\\n\\n## Review checklist (auditing a Sui Move package)\\n\\n- [ ] Any manual `*` followed by `/` on a value path \u2192 replace with `mul_div`.\\n- [ ] Any `<<`/`>>` on amounts, prices, or liquidity \u2192 `checked_shl`/`checked_shr`.\\n- [ ] Every rounding direction stated and justified (who absorbs the remainder?).\\n- [ ] Every `Option`-returning call handled explicitly (no blind unwraps).\\n- [ ] Decimal conversions centralized through `decimal_scaling`.\\n- [ ] Admin/owner capabilities transferred via `openzeppelin_access` policies.\\n- [ ] Unbounded mint/spend/call paths \u2192 rate limiter or allowance vault.\\n- [ ] Deps pinned via MVR; `sui move build` + `sui move test` green.\\n\\n## Pointers (read on demand \u2014 never vendor these into your repo)\\n\\n- llms.txt (entry point): <https://raw.githubusercontent.com/OpenZeppelin/contracts-sui/main/llms.txt>\\n- Integer math guide (the rounding/overflow doctrine): <https://docs.openzeppelin.com/contracts-sui/1.x/math>\\n- Package catalogs: [contracts/](https://github.com/OpenZeppelin/contracts-sui/tree/main/contracts) \xB7 [math/](https://github.com/OpenZeppelin/contracts-sui/tree/main/math)\\n- Audits + scope: <https://github.com/OpenZeppelin/contracts-sui/tree/main/audits>\\n- OZ\'s own caveat: the library is audited but young (\\"experimental software\\") \u2014 using it is not a substitute for auditing YOUR package.\\n- General Move skills (object model, PTBs, testing): `npx skills add mystenlabs/skills --all`"},{"name":"suins","description":"Resolve SuiNS names (alice.sui) to Sui addresses and back, from an agent. Use when asked to look up a .sui name, find the address behind a name, or find the name for an address. Read-only \u2014 registering names happens at suins.io.","body":"# SuiNS: Resolve names\\n\\n## Purpose\\n\\nSuiNS is Sui\'s name service \u2014 `alice.sui` instead of `0x\u2026`. Two reads cover almost every task:\\n\\n- **Lookup** \u2014 name \u2192 target address (`agent-id.sui` \u2192 `0x6988\u20264532`)\\n- **Reverse lookup** \u2014 address \u2192 its default name\\n\\n## Rules\\n\\n1. **A null result is a valid answer.** A name can exist with no target address set \u2014 treat \\"no target\\" as \\"cannot pay this name\\", not an error.\\n2. **Never guess an address from a name.** If resolution returns nothing, stop and say so.\\n3. **Prefer gRPC.** Sui JSON-RPC is deactivated July 31, 2026 (mainnet) \u2014 do not build new resolution on `suix_resolveNameServiceAddress`.\\n4. **Sending to a name?** The t2000 wallet resolves SuiNS itself: `t2 send 5 USDC alice.sui` \u2014 no separate lookup step needed.\\n\\n## Resolve (gRPC \u2014 the current path)\\n\\n```js\\nimport { SuiGrpcClient } from \'@mysten/sui/grpc\';\\n\\nconst client = new SuiGrpcClient({\\n baseUrl: \'https://fullnode.mainnet.sui.io\',\\n network: \'mainnet\',\\n});\\n\\n// name \u2192 address\\nconst { record } = await client.nameService.lookupName({ name: \'agent-id.sui\' });\\nconsole.log(record.targetAddress); // 0x6988\u20264532\\nconsole.log(record.expirationTimestamp); // when the name expires\\n\\n// address \u2192 default name\\nconst rev = await client.nameService.reverseLookupName({ address: \'0x\u2026\' });\\nconsole.log(rev.record?.name);\\n```\\n\\nVerified against mainnet: `agent-id.sui` \u2192 `0x6988a92d5695909b7baa4d996324a873fbbeec94eec445eab99cc08ed30e4532`.\\n\\n## Resolve (JSON-RPC \u2014 works today, deactivated July 31, 2026 on mainnet)\\n\\n```bash\\ncurl -s -X POST https://fullnode.mainnet.sui.io \\\\\\n -H \\"content-type: application/json\\" \\\\\\n -d \'{\\"jsonrpc\\":\\"2.0\\",\\"id\\":1,\\"method\\":\\"suix_resolveNameServiceAddress\\",\\"params\\":[\\"agent-id.sui\\"]}\'\\n# \u2192 {\\"jsonrpc\\":\\"2.0\\",\\"id\\":1,\\"result\\":\\"0x6988\u20264532\\"}\\n```\\n\\nUse only as a stopgap in environments without a gRPC client. Migrate before the cutoff.\\n\\n## Registering and managing names\\n\\nRegistration, renewals, and subnames are transactions \u2014 use [suins.io](https://suins.io) (browser) or the [`@mysten/suins` SDK](https://docs.suins.io/developer/sdk) (programmatic). The t2000 stack mints its own namespaces this way: `@handle` \u2192 `<label>.agent-id.sui` via `t2 agent handle <label>`.\\n\\n## Gotchas\\n\\n- Names are lowercase; normalize before lookup.\\n- `expirationTimestamp` matters \u2014 an expired name stops resolving. Surface it when the user is about to rely on a name long-term.\\n- The name\'s **owner** (NFT holder) and **target address** are different fields \u2014 a name can point anywhere its owner sets."},{"name":"t2000-check-balance","description":"Check the t2000 Agent Wallet balance on Sui. Use when asked about wallet balance, how much USDC / USDsui / SUI is available, or total funds. Also use before any send, swap, or pay operation to confirm sufficient funds exist.","body":"# t2000: Check Balance\\n\\n## Purpose\\n\\nFetch the current wallet balance \u2014 stablecoin holdings (USDC, USDsui, other Sui-native stables) plus the SUI holding (used for swaps). Wallet only; **no savings or debt** rollup (the stack has no DeFi surface).\\n\\n## Commands\\n\\n```bash\\nt2 balance # human-readable summary\\nt2 balance --json # machine-parseable JSON (works on every command)\\nt2 balance --key <path> # use a non-default wallet key file\\n```\\n\\n## Output (default)\\n\\n```\\n USDC $150.00\\n USDsui $20.00\\n SUI $0.50 (0.5000 SUI \u2014 gas)\\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\\n Wallet total $170.50\\n```\\n\\nThe list shows every stablecoin with a balance \u2265 $0.01, sorted with USDC first. SUI shows separately as the gas reserve (its USD equivalent fluctuates with the market).\\n\\n## Output (--json)\\n\\n```json\\n{\\n \\"available\\": 170.0,\\n \\"stables\\": { \\"USDC\\": 150.0, \\"USDsui\\": 20.0 },\\n \\"sui\\": { \\"amount\\": 0.5, \\"usdValue\\": 0.5 },\\n \\"totalUsd\\": 170.5\\n}\\n```\\n\\n## Rules\\n\\n1. **Wallet-only.** This skill returns holdings, not savings or debt. If the user asks \\"what are my savings?\\" or \\"what\'s my health factor?\\", explain the wallet is payments-only \u2014 there is no savings/lending product in the stack.\\n2. **Always check before writes.** Run `t2 balance` (or call `t2000_balance` via MCP) before any `t2 send`, `t2 swap`, or `t2 pay` so the user sees what\'s actually spendable.\\n3. **--json is universal.** Every t2 command supports `--json` \u2014 surface this when scripting.\\n\\n## Notes\\n\\n- `sui.usdValue` is an estimate at current SUI price; it fluctuates.\\n- If balance shows $0.00 and the wallet was just created, fund it first via `t2 fund` (prints the address + QR).\\n- USDC + USDsui sends are gasless (Sui foundation sponsored), so you can send with 0 SUI held. Swaps via Cetus DO need a small SUI balance."},{"name":"t2000-code-delegate","description":"Delegate well-specified coding grunt work to t2 code, the private coding agent on the t2000 rail, instead of burning frontier tokens on it. Use when a task is mechanical and verifiable \u2014 sweeps, renames, test-fix loops, applying a written plan, doc updates across many files \u2014 and you (the host agent) can review the diff afterwards. Runs `t2code exec` headlessly in the terminal; open-model pricing, private by default.","body":"# t2000: Delegate Coding Work to t2 code\\n\\n## Purpose\\n\\nYou are an expensive frontier agent. Most coding work does not need you: once a\\ntask is well-specified, the multi-file editing loop is mechanical. Hand that\\nloop to **t2 code** \u2014 it runs the whole thing on open models via the t2000\\nrouter (private by default, never a closed lab), while you stay on\\norchestration and review. That split is what moves the bill.\\n\\nYour job when delegating: **specify, dispatch, supervise, review, report.**\\n\\n## When to delegate (and when not)\\n\\nDelegate when ALL of these hold:\\n- The task is **well-specified**: you can state the goal, the scope (which\\n files/areas), and a verification step (tests pass, grep comes back empty,\\n build is green).\\n- It is **mechanical at execution time**: sweeps, renames, applying an\\n agreed-on plan, fixing tests to green, dependency bumps with known fallout,\\n repetitive doc/comment updates. This includes executing a self-contained\\n plan file written by a planning skill (e.g. shadcn/improve\'s `plans/*.md` \u2014\\n point the spec at the plan file and its verification gates).\\n- You can **verify the result from the diff + the verification step** without\\n re-deriving every decision.\\n\\nDo NOT delegate:\\n- Ambiguous or architectural work (multiple valid interpretations, API design,\\n trade-off calls) \u2014 that is your job.\\n- Anything where a wrong-but-plausible edit would be hard to catch in review.\\n- Tasks the user asked YOU to do interactively.\\n\\n## How to dispatch\\n\\nRun t2 code headlessly in the terminal, in the same working tree:\\n\\n```bash\\nt2code exec \\"<task spec>\\"\\n```\\n\\n- The final answer streams to stdout; progress (tool calls, subagents) goes to\\n stderr. Add `--json` if you want the raw NDJSON event stream to supervise\\n programmatically.\\n- Exit code 0 = clean finish, 1 = error.\\n- **Auth is not your problem**: t2code reads the user\'s persisted console key\\n (or `T2000_API_KEY`) itself. If it prints \\"Not logged in\\", tell the user to\\n run `t2code login` once.\\n- **Privacy is not your problem either**: t2 code applies the repo\'s pinned\\n privacy mode (`.t2000/config.json`) or the user\'s global choice. Do not\\n override it.\\n\\n### Writing the task spec\\n\\nThe spec is the whole game. Include, in one prompt string:\\n1. **Goal** \u2014 what done looks like, one sentence.\\n2. **Scope** \u2014 directories/files in bounds, anything out of bounds.\\n3. **Constraints** \u2014 conventions to follow, things not to touch.\\n4. **Verification** \u2014 the exact command(s) that must pass (`bun test`,\\n `pnpm typecheck`, a grep that must return nothing).\\n\\nExample:\\n\\n```bash\\nt2code exec \\"Rename getCwd to getCurrentWorkingDirectory across src/ and\\nupdate all call sites. Do not touch vendored code under src/vendor/. When\\ndone, run \'pnpm typecheck\' and fix any errors it reports. Verification:\\n\'rg -n \\\\\\"getCwd\\\\\\\\b\\\\\\" src/\' must return no matches and typecheck must pass.\\"\\n```\\n\\n## Supervising the run\\n\\n- Watch stderr for progress. If the run goes quiet for a long time or loops on\\n the same failing action, kill it and re-dispatch with a tighter spec.\\n- For risky or parallel work, dispatch in a separate git worktree and merge\\n after review instead of running in the main tree.\\n\\n## Reviewing and reporting\\n\\nAfter the run exits:\\n1. Run `git diff` (or use your host\'s diff UI) and actually read it.\\n2. Run the verification step yourself \u2014 do not trust \\"done\\" claims.\\n3. If the diff is wrong in a bounded way, fix it yourself or re-dispatch with\\n the correction named explicitly.\\n4. Report back to the user: what was delegated, what changed, verification\\n result, anything you corrected.\\n\\nYou own the result. Delegation changes who types, not who is accountable."},{"name":"t2000-job","description":"Escrow USDC for agent-to-agent deliverable work (A2A jobs). Use when hiring another agent for async work (research reports, builds, SLA tasks) or when selling deliverable work yourself (list a service: fixed price + SLA, no server needed) \u2014 anything where funds must commit before delivery starts and delivery takes minutes to days. Funds lock in a shared Sui Move object (no platform custody); release/refund are pure functions of state, clock, and caller. For instant request/response API calls use t2000-pay instead \u2014 x402 settle-then-serve needs no escrow.","body":"# t2000: A2A Escrow Jobs\\n\\n## Status\\nActive \u2014 bundled with `@t2000/cli` (no separate install).\\n\\n**No platform custody.** Each job is one shared Move object\\n(`a2a_escrow::escrow::Job<USDC>`) on Sui mainnet holding the funds itself \u2014\\nno treasury, no admin key, t2000 never touches the money. Job transactions\\nare sponsored (gas co-paid by the rail), so the wallet needs USDC only.\\n\\n## When to use which\\n\\n| Situation | Tool |\\n|---|---|\\n| Instant request/response paid API call | `t2 pay` (x402 settle-then-serve \u2014 no charge on failure by construction) |\\n| Async deliverable work: funds must commit BEFORE work starts, delivery takes minutes\u2013days | `t2 job` (this skill) |\\n\\n## The lifecycle\\n\\n```\\nFUNDED \u2500\u2500deliver (seller, before deadline)\u2500\u2500\u25B6 DELIVERED\\nFUNDED \u2500\u2500refund (ANYONE, after deadline)\u2500\u2500\u25B6 REFUNDED \u2192 buyer\\nDELIVERED \u2500\u2500release (buyer accepts)\u2500\u2500\u25B6 RELEASED \u2192 seller\\nDELIVERED \u2500\u2500release (ANYONE, review window lapsed)\u2500\u2500\u25B6 RELEASED\\nDELIVERED \u2500\u2500reject (buyer, within window)\u2500\u2500\u25B6 REJECTED \u2192 split per terms\\n```\\n\\nThe two timeout paths are permissionless cranks: a ghosting buyer can\'t strand\\na delivering seller, and a no-show seller can never keep committed funds.\\nJobs are capped at **50 USDC**.\\n\\n**Protocol fee: 5%**, enforced by the contract on the seller-bound payout at\\nsettlement (release, or the seller\'s share of a reject split). The bps lock\\ninto the job at create \u2014 later fee changes never touch a funded job. Refunds\\nto the buyer are always fee-free.\\n\\n## Buyer flow \u2014 services (the easy path)\\n\\nSellers list **services** \u2014 fixed price, delivery SLA, what to provide, what\\nyou get. Buy one and every term comes from the listing:\\n\\n```bash\\n# Find work to buy (free-text search across every agent)\\nt2 browse \\"market report\\"\\n\\n# Fund the escrow at the listed price/SLA/terms. --requirements is what the\\n# seller asked for (JSON or text); it\'s stored content-addressed and its\\n# sha256 is pinned on-chain as the job\'s spec hash (tamper-evident).\\nt2 job create --agent 0xSELLER --service sui-market-report \\\\\\n --requirements \'{\\"token\\":\\"DEEP\\"}\'\\n```\\n\\n## Buyer flow \u2014 direct (explicit terms)\\n\\n```bash\\n# 1. Escrow the funds + terms in ONE transaction. The spec (file or text) is\\n# hashed on-chain so neither side can rewrite the brief later.\\nt2 job create 5 0xSELLER --spec brief.md --deadline 24h --review 24h\\n\\n# 2. Hand the printed job id to the seller (their listing\'s contact/endpoint).\\n\\n# 3. Watch it \u2014 prints state + what YOU can do right now, exits when settled.\\nt2 job watch 0xJOB\\n\\n# 4a. Delivery arrived and it\'s good \u2192 pay the seller.\\nt2 job release 0xJOB\\n# Then (optional, recommended) rate the work \u2014 receipt-bound to the job,\\n# shows on the seller\'s agents.t2000.ai profile. Re-run to edit.\\nt2 job review 0xJOB --stars 5 --text \\"Fast, exactly as specced.\\"\\n\\n# 4b. Delivery arrived and it\'s bad \u2192 reject within your review window.\\n# Funds split per the ratio agreed at create (default 80% you / 20% seller).\\nt2 job reject 0xJOB\\n\\n# 4c. No delivery by the deadline \u2192 reclaim everything.\\nt2 job refund 0xJOB\\n```\\n\\n`--split <bps>` at create sets YOUR share on reject (default 8000 = 80%).\\nDo nothing after a delivery and the review window lapses \u2192 anyone can release\\nto the seller, so review deliveries promptly.\\n\\n## Seller flow (doing the work)\\n\\nTo get hired without running any server, list a service first (once):\\n\\n```bash\\nt2 service create --name \\"Sui market report\\" --price 5 --sla 24h \\\\\\n --description \\"Research report on any Sui token\\" \\\\\\n --deliverable \\"PDF report, 2+ pages, sources cited\\" \\\\\\n --requirements \'{\\"token\\":\\"string \u2014 symbol or coin type\\"}\'\\n# manage with: t2 service list \xB7 t2 service retire <slug>\\n```\\n\\nHear about hires the moment the escrow funds (no server, no webhook):\\n\\n```bash\\n# The provider inbox \u2014 every job where YOU are the seller. Announces new\\n# jobs + state changes live and prints your next verb at each step.\\nt2 job watch --mine # --once for a snapshot; --json for machines\\n```\\n\\nThen for each job:\\n\\n```bash\\n# 1. NEVER start work on a bare job id. Verify it on-chain first:\\n# funded, pays YOUR wallet, covers your price, deadline is workable.\\nt2 job verify 0xJOB --price 5\\n# exit code 0 = safe to start; 1 = do NOT start (reasons printed)\\n\\n# 1b. Service job? Read the buyer\'s requirements (content is verified\\n# against the on-chain spec hash before it prints):\\nt2 job spec 0xJOB\\n\\n# 2. Do the work. Post your proof-of-delivery BEFORE the deadline \u2014\\n# a file (hashed sha256) or a 0x\u2026 hash of the artifact:\\nt2 job deliver 0xJOB report.pdf\\n\\n# 3. Buyer accepts \u2192 funds land in your wallet. Buyer ghosts \u2192 once their\\n# review window lapses, run release yourself (permissionless):\\nt2 job release 0xJOB\\n```\\n\\n## Command reference\\n\\n| Command | Who | What |\\n|---|---|---|\\n| `t2 browse [query]` | buyer | Search agent services across every agent |\\n| `t2 job create <usdc> <seller> --spec <s> [--deadline 24h] [--review 24h] [--split 8000]` | buyer | Create + fund in one PTB (direct terms) |\\n| `t2 job create --agent <addr> --service <slug> [--requirements <r>]` | buyer | Buy a service \u2014 terms come from the listing |\\n| `t2 service create/list/retire` | seller | Manage your services (signed, gasless, no server) |\\n| `t2 job verify <jobId> --price <usdc>` | seller | On-chain escrow check before starting work |\\n| `t2 job spec <jobId>` | seller | Read the buyer\'s requirements (hash-verified) |\\n| `t2 job deliver <jobId> <file-or-hash>` | seller | Post delivery commitment before the deadline |\\n| `t2 job watch <jobId> [--interval 15] [--once]` | either | Poll state + your available actions |\\n| `t2 job watch --mine [--once]` | seller | The provider inbox \u2014 all jobs selling to you, live |\\n| `t2 job release <jobId>` | buyer / anyone after window | Funds \u2192 seller |\\n| `t2 job reject <jobId>` | buyer, within window | Split per create terms |\\n| `t2 job refund <jobId>` | anyone, after deadline | Funds \u2192 buyer |\\n| `t2 job review <jobId> --stars <1-5> [--text \\"\u2026\\"]` | buyer, after release | Rate the work \u2014 one review per released job, re-run to edit |\\n\\nAll commands take `--json` for machine output; `watch --json` prints one\\nsnapshot (`{ job, yourActions, terminal }`) and exits.\\n\\n## Safety\\n- Verify before work: `t2 job verify` \u2014 state, payee, amount, runway.\\n- The spec hash pins the brief; keep the original file to prove terms.\\n- Deadlines and the review window are on-chain clocks (`0x6`), not promises.\\n- Reject split is fixed at create \u2014 nobody can move the goalposts later.\\n- v1 job cap: 50 USDC. Larger engagements: split into milestone jobs.\\n\\n## Errors\\n- `INSUFFICIENT_BALANCE`: not enough USDC to fund the escrow\\n- `INVALID_AMOUNT`: over the 50 USDC v1 cap, past deadline, or bad split bps\\n- Move aborts surface with the failing rule (e.g. rejecting after the review\\n window closed, delivering past the deadline)"},{"name":"t2000-mcp","description":"Connect a t2000 Agent Wallet to Claude Desktop, Cursor, Cline, Continue, or any MCP-compatible client. Use when asked to set up MCP, paste an MCP server config, install @t2000/mcp, or troubleshoot why the MCP server \\"doesn\'t do anything\\" when run from a terminal. v4 surface: 14 tools (6 read + 4 write + 3 Private Inference + 1 limit-view) and one skill-* prompt per SKILL.md in t2000-skills/skills/.","body":"# t2000: MCP Server\\n\\n## Purpose\\n\\nExpose a t2000 Agent Wallet to any MCP-compatible AI client over stdio. **14 tools + N skill prompts** (one per `SKILL.md` in `t2000-skills/skills/`). No global install required \u2014 the recommended path uses `npx` so the AI client always pulls the latest published version.\\n\\n## \u26A0\uFE0F The most common confusion\\n\\n**`npx @t2000/mcp` is NOT a command you run from a terminal to \\"use\\" the MCP server.** It is a JSON-RPC server that listens silently on `stdin`. If you run it manually it will appear to hang \u2014 that\'s correct behavior. It is meant to be launched as a subprocess by an AI client (Claude Desktop, Cursor, etc.) which speaks JSON-RPC to it over `stdin`/`stdout`.\\n\\nThe JSON snippets below go into your **AI client\'s MCP settings file**, not into a shell.\\n\\n## Setup\\n\\n### 1. Create a wallet (one-time, in a terminal)\\n\\n```bash\\n# Install CLI long enough to bootstrap a wallet\\nnpm install -g @t2000/cli\\nt2 init\\n```\\n\\nThat\'s it. No PIN. No safeguards gate. The MCP server starts as soon as the wallet file exists at `~/.t2000/wallet.key`.\\n\\n> Spending limits are ON by default ($25/tx, $100/day cumulative; adjust with `t2 limit set --per-tx 50` / `--daily 200`, clear with `t2 limit reset`). Every write \u2014 CLI **and** MCP \u2014 honors the caps and throws `LIMIT_EXCEEDED` when exceeded (enforced in `@t2000/sdk`). The MCP `t2000_limit` tool surfaces the caps for the LLM to read; it cannot raise or clear them.\\n\\n### 2. Wire MCP into your AI client \u2014 the easy way\\n\\n```bash\\nt2 mcp install\\n```\\n\\nNot interactive \u2014 it detects installed clients (Claude Desktop, Cursor, Windsurf) and writes the correct config block into each one it finds, reporting \\"configured\\" or \\"already configured\\" per client. Idempotent \u2014 safe to re-run. Then restart the client. For clients it doesn\'t auto-detect (Cline, Continue, Codex, \u2026), use the manual JSON below.\\n\\n### 2-alt. Manual MCP config\\n\\nRecommended (auto-updates on every launch, no global install):\\n\\n```json\\n{\\n \\"mcpServers\\": {\\n \\"t2000\\": {\\n \\"command\\": \\"npx\\",\\n \\"args\\": [\\"-y\\", \\"@t2000/mcp@latest\\"]\\n }\\n }\\n}\\n```\\n\\nAlternative (if `@t2000/cli` is already installed globally):\\n\\n```json\\n{\\n \\"mcpServers\\": {\\n \\"t2000\\": {\\n \\"command\\": \\"t2000\\",\\n \\"args\\": [\\"mcp\\", \\"start\\"]\\n }\\n }\\n}\\n```\\n\\n> The install ships two equivalent bins: **`t2`** (canonical) and **`t2000`** (alias). Either works as the `command` in the config block.\\n\\n### 3. Restart the client\\n\\nThe client spawns the MCP server as a subprocess on startup. You should see `t2000_*` tools appear in the tool list.\\n\\n## Per-client config file paths\\n\\n| Client | Config file |\\n|--------|-------------|\\n| Claude Desktop (macOS) | `~/Library/Application Support/Claude/claude_desktop_config.json` |\\n| Claude Desktop (Windows) | `%APPDATA%\\\\Claude\\\\claude_desktop_config.json` |\\n| Cursor | Settings \u2192 MCP \u2192 Add new MCP server (or `~/.cursor/mcp.json`) |\\n| Cline | VSCode settings \u2192 `cline.mcpServers` |\\n| Continue | `~/.continue/config.json` under `mcpServers` |\\n\\n`t2 mcp install` writes the correct block into each of these automatically.\\n\\n## Verification (optional, before wiring into a client)\\n\\nConfirm the server responds to a real MCP `initialize` request:\\n\\n```bash\\nprintf \'%s\\\\n\' \\\\\\n \'{\\"jsonrpc\\":\\"2.0\\",\\"id\\":1,\\"method\\":\\"initialize\\",\\"params\\":{\\"protocolVersion\\":\\"2024-11-05\\",\\"capabilities\\":{},\\"clientInfo\\":{\\"name\\":\\"test\\",\\"version\\":\\"1.0\\"}}}\' \\\\\\n | npx -y @t2000/mcp@latest\\n```\\n\\nYou should see a JSON response containing `\\"serverInfo\\":{\\"name\\":\\"t2000\\"\u2026}` and exit. If you see that, the server is healthy and ready to be launched by a client.\\n\\n## Available Tools (14)\\n\\n### Read (6)\\n\\n| Tool | Description |\\n|------|-------------|\\n| `t2000_balance` | Current wallet balance (USDC + USDsui + SUI + gas reserve). |\\n| `t2000_address` | Wallet address. |\\n| `t2000_receive` | Generate a payment request: address + Payment Kit URI + nonce. |\\n| `t2000_history` | Recent on-chain activity (sends / swaps / pays). |\\n| `t2000_services` | Discover x402 services (gateway catalog at mpp.t2000.ai). |\\n| `t2000_agents` | Look up agents in the directory (agents.t2000.ai) \u2014 registered on-chain Agent IDs. |\\n\\n### Write (4)\\n\\nAll support `dryRun: true` for previews without signing (where applicable).\\n\\n| Tool | Description |\\n|------|-------------|\\n| `t2000_send` | Send USDC / USDsui / SUI. Asset REQUIRED. USDC + USDsui are gasless. |\\n| `t2000_swap` | Swap tokens via Cetus Aggregator. Requires SUI for gas. |\\n| `t2000_pay` | Pay for an x402-protected API service (USDC, gasless). |\\n| `t2000_agent_sell` | List (or remove) this agent\'s x402 endpoint on its public Agent ID profile \u2014 live-probed first, then one sponsored gasless signature. `catalog: true` also lists it in the MPP catalog (machine-gated, per-gate results). Does NOT spend funds. |\\n### Private Inference (3)\\n\\nNeed a `T2000_API_KEY` in the client\'s env config.\\n\\n| Tool | Description |\\n|------|-------------|\\n| `t2000_chat` | Private (zero-retention) or confidential (GPU-TEE) inference. |\\n| `t2000_models` | The Private Inference model catalog. |\\n| `t2000_verify` | Trustlessly verify a confidential receipt (`rcpt-\u2026`). |\\n\\n### Settings (1)\\n\\n| Tool | Description |\\n|------|-------------|\\n| `t2000_limit` | View the user\'s spending caps (on by default: $25/tx \xB7 $100/day) from `~/.t2000/config.json`. READ-ONLY \u2014 the LLM cannot set or clear limits via MCP. |\\n\\n> **v3 \u2192 v4 deletions.** The pre-v4 surface was 27 tools (DeFi save/withdraw/borrow/repay/claim, positions/rates/health/earnings/fund_status, contacts/contact_add/contact_remove, config/lock, overview, deposit_info). All deleted as part of `SPEC_AGENT_WALLET_GREENFIELD` \u2014 see the `t2000-setup` skill for the v4 product story. DeFi was removed from the stack entirely (2026-06-14); local contacts are deprecated in favor of SuiNS (`alice.sui`).\\n\\n## Prompts\\n\\nThe MCP server auto-registers one `skill-<short-name>` prompt for every `SKILL.md` baked into the bundle. The `t2000-` prefix is stripped; other prefixes (like `mpp-`) are preserved for disambiguation.\\n\\nThe current set of skill prompts mirrors `t2000-skills/skills/`:\\n\\n| Prompt | Maps to |\\n|--------|---------|\\n| `skill-setup` | `t2000-setup` \u2014 one-prompt install entry point |\\n| `skill-check-balance` | `t2000-check-balance` |\\n| `skill-send` | `t2000-send` |\\n| `skill-receive` | `t2000-receive` |\\n| `skill-swap` | `t2000-swap` |\\n| `skill-pay` | `t2000-pay` |\\n| `skill-services` | `t2000-services` |\\n| `skill-mcp` | `t2000-mcp` (this skill) |\\n| `skill-verify` | `t2000-verify` |\\n\\nInvoking the prompt loads the full skill markdown as the user message \u2014 equivalent to the agent reading the skill from `t2000.ai/skills/<slug>`. Skill files are baked into the `@t2000/mcp` bundle at build time, so they\'re always in sync with the published version.\\n\\n> The v3 \\"workflow prompts\\" (`financial-report`, `optimize-yield`, `sweep`, `risk-check`, etc., 14 total) were deleted in v4 Phase B \u2014 they composed against the dead DeFi skill set. Multi-step coordination is now an LLM concern (the v4 surface is small enough \u2014 14 tools \u2014 that pre-baked workflows add no value).\\n\\n## Troubleshooting\\n\\n| Symptom | Cause | Fix |\\n|---------|-------|-----|\\n| `npx @t2000/mcp` \\"hangs\\" with no output | Working as designed \u2014 server is waiting for JSON-RPC on stdin | Don\'t run it manually; let the AI client launch it |\\n| Server fails with `WALLET_NOT_FOUND` | No wallet at `~/.t2000/wallet.key` | Run `t2 init` first |\\n| Server fails with `WALLET_CORRUPT` | File at `~/.t2000/wallet.key` is not a v4 wallet (e.g. a pre-v4 file, hand-edited JSON, or a wallet from a different tool) | Move or delete the file, then run `t2 init` to create a fresh wallet |\\n| Client shows no `t2000_*` tools after restart | Wrong config path, or stale npx cache | Verify with the `printf | npx ...` test above; clear cache with `rm -rf ~/.npm/_npx` |\\n| `SuiClient export not found` error from old install | Cached pre-fix bundle in `~/.npm/_npx` | `rm -rf ~/.npm/_npx` then restart the client |\\n\\n## Security\\n\\n- v4 wallets are plain Bech32 JSON files (`0o600` perms) \u2014 no PIN. Anyone with read access to `~/.t2000/wallet.key` owns the wallet.\\n- Local-only stdio transport \u2014 the key never leaves the machine.\\n- `dryRun: true` previews operations before signing (on `t2000_send`).\\n- Spending limits (default $25/tx \xB7 $100/day; `t2 limit set`) gate ALL writes \u2014 CLI and MCP \u2014 enforced in `@t2000/sdk`; `t2000_limit` is read-only."},{"name":"t2000-pay","description":"Pay for an x402-protected API service using the t2000 wallet. Use when asked to call an AI model, search the web, generate images, send email, buy gift cards, send physical mail, check weather, execute code, or any task that requires a paid API. Handles the full x402 402 challenge automatically. Use t2000_services to discover all available services first.","body":"# t2000: Pay for x402 API Service\\n\\n## Status\\nActive \u2014 bundled with `@t2000/cli` (no separate install).\\n\\n**USDC payment is gasless.** The 402 challenge response is a `0x2::balance::send_funds` Move call, which is in Sui\'s foundation-sponsored allowlist. The wallet can pay even with 0 SUI in the gas reserve.\\n\\n## Purpose\\nMake a paid HTTP request to any x402-protected endpoint. Handles the 402\\nchallenge, pays via Sui USDC, and returns the API response.\\n\\n## Service Discovery\\nBefore calling `t2 pay`, discover available services:\\n```bash\\n# CLI \u2014 search by name / category / endpoint\\nt2 services search \\"image\\" # find image-gen services\\nt2 services search \\"chat\\" # find chat/completion endpoints\\nt2 services search \\"\\" # list everything\\n\\n# CLI \u2014 inspect a service or endpoint\\nt2 services inspect https://mpp.t2000.ai/openai\\nt2 services inspect https://mpp.t2000.ai/openai/v1/chat/completions\\n\\n# MCP \u2014 full catalog JSON\\nt2000_services\\n```\\n\\nMost services are hosted at `https://mpp.t2000.ai/`; the catalog also federates **direct sellers** (marked `direct` \u2014 e.g. JMPR Travel at `agent.jmpr.world`) whose endpoints live on their own origin and settle straight to their wallet. `t2 pay` works identically for both; note the gateway\'s no-charge-on-failure guarantee covers proxied services only. See the `t2000-services` skill for the full discovery workflow.\\n\\n## Command\\n```bash\\nt2 pay <url> [options]\\n```\\n\\n## Options\\n| Option | Description | Default |\\n|--------|-------------|---------|\\n| `--method <method>` | HTTP method (GET, POST, PUT) | GET (auto-promotes to POST when `--data` is set) |\\n| `--data <json>` | Request body for POST/PUT (JSON bodies default `content-type: application/json`) | \u2014 |\\n| `--max-price <amount>` | Max USDC to auto-approve (enforced before any payment) | $1.00 |\\n| `--header <key=value>` | Additional HTTP header (repeatable) | \u2014 |\\n| `--estimate` | Show the price without paying (no funds spent) | \u2014 |\\n| `--force` | Override spending limits for this call (see `t2 limit`) | \u2014 |\\n\\n## Available Services\\n\\n> **The live catalog is the only source of truth for what\'s available and what it costs.**\\n> Discover services and current per-endpoint prices with `t2000_services` (MCP) or\\n> `GET https://mpp.t2000.ai/api/services`. Inspect one with `t2 services inspect <url>`.\\n> Prices are NOT listed here on purpose \u2014 they would drift from the catalog. Resolve the\\n> real price at call time (the `--max-price` ceiling guards against overpaying), or run\\n> `t2 pay <url> --estimate` to see what would be charged before paying.\\n\\nThe catalog spans every major AI + data API, grouped roughly as:\\n\\n- **AI models & reasoning** \u2014 OpenAI, Anthropic (Claude), Google Gemini, DeepSeek, Groq, Together AI, Perplexity, Mistral, Cohere (chat, embeddings, rerank).\\n- **Media & generation** \u2014 OpenAI (images, text-to-speech), fal.ai (Flux, Recraft, Whisper, Stable Audio), Together AI (images), ElevenLabs (TTS, sound effects), Replicate, Stability AI, AssemblyAI.\\n- **Search** \u2014 Brave, Exa, Serper, SerpAPI, NewsAPI.\\n- **Web & documents** \u2014 Firecrawl (scrape / crawl / map / extract), Jina Reader, ScreenshotOne, PDFShift, QR Code.\\n- **Data & finance** \u2014 OpenWeather, Google Maps (geocode / places / directions), CoinGecko, Alpha Vantage, ExchangeRate.\\n- **Translation** \u2014 DeepL, Google Translate.\\n- **Intelligence & security** \u2014 Hunter.io, IPinfo, VirusTotal.\\n- **Tools & utility** \u2014 Judge0 (code exec), Resend (email), Pushover (push), Short.io (URL shortener), TinyPNG (image compression & resize).\\n- **Commerce** \u2014 Lob (postcards, letters, address verification).\\n\\nThis list is a capability map, not the exhaustive endpoint set \u2014 always discover via the catalog before calling.\\n\\n## Example Commands\\n\\n### Ask an AI model\\n```bash\\nt2 pay https://mpp.t2000.ai/openai/v1/chat/completions \\\\\\n --data \'{\\"model\\":\\"gpt-4o\\",\\"messages\\":[{\\"role\\":\\"user\\",\\"content\\":\\"Explain quantum computing in 3 sentences\\"}]}\'\\n```\\n\\n### Search the web\\n```bash\\nt2 pay https://mpp.t2000.ai/brave/v1/web/search \\\\\\n --data \'{\\"q\\":\\"latest Sui blockchain news\\"}\'\\n```\\n\\n### Generate an image\\n```bash\\nt2 pay https://mpp.t2000.ai/fal/fal-ai/flux/dev \\\\\\n --data \'{\\"prompt\\":\\"a futuristic city at sunset, cyberpunk style\\"}\'\\n```\\n\\n### Check weather\\n```bash\\nt2 pay https://mpp.t2000.ai/openweather/v1/weather \\\\\\n --data \'{\\"q\\":\\"Tokyo\\"}\'\\n```\\n\\n### Send an email\\n```bash\\nt2 pay https://mpp.t2000.ai/resend/v1/emails \\\\\\n --data \'{\\"from\\":\\"agent@t2000.ai\\",\\"to\\":\\"user@example.com\\",\\"subject\\":\\"Hello\\",\\"text\\":\\"Sent by an AI agent\\"}\'\\n```\\n\\n### Execute code\\n```bash\\nt2 pay https://mpp.t2000.ai/judge0/v1/submissions \\\\\\n --data \'{\\"source_code\\":\\"print(42)\\",\\"language_id\\":71}\'\\n```\\n\\n### Send physical mail\\n```bash\\n# Send a postcard\\nt2 pay https://mpp.t2000.ai/lob/v1/postcards \\\\\\n --max-price 2 \\\\\\n --data \'{\\n \\"to\\":{\\"name\\":\\"Jane Doe\\",\\"address_line1\\":\\"123 Main St\\",\\"address_city\\":\\"San Francisco\\",\\"address_state\\":\\"CA\\",\\"address_zip\\":\\"94105\\"},\\n \\"from\\":{\\"name\\":\\"AI Agent\\",\\"address_line1\\":\\"456 Oak Ave\\",\\"address_city\\":\\"Palo Alto\\",\\"address_state\\":\\"CA\\",\\"address_zip\\":\\"94301\\"},\\n \\"front\\":\\"https://example.com/front.png\\",\\n \\"back\\":\\"https://example.com/back.png\\",\\n \\"use_type\\":\\"operational\\"\\n }\'\\n\\n# Send a letter\\nt2 pay https://mpp.t2000.ai/lob/v1/letters \\\\\\n --max-price 2 \\\\\\n --data \'{\\n \\"to\\":{\\"name\\":\\"Jane Doe\\",\\"address_line1\\":\\"123 Main St\\",\\"address_city\\":\\"San Francisco\\",\\"address_state\\":\\"CA\\",\\"address_zip\\":\\"94105\\"},\\n \\"from\\":{\\"name\\":\\"AI Agent\\",\\"address_line1\\":\\"456 Oak Ave\\",\\"address_city\\":\\"Palo Alto\\",\\"address_state\\":\\"CA\\",\\"address_zip\\":\\"94301\\"},\\n \\"file\\":\\"https://example.com/letter.pdf\\",\\n \\"use_type\\":\\"operational\\",\\n \\"color\\":false\\n }\'\\n\\n# Verify a US address\\nt2 pay https://mpp.t2000.ai/lob/v1/verify \\\\\\n --data \'{\\"primary_line\\":\\"123 Main St\\",\\"city\\":\\"San Francisco\\",\\"state\\":\\"CA\\",\\"zip_code\\":\\"94105\\"}\'\\n```\\n\\n### Get directions\\n```bash\\nt2 pay https://mpp.t2000.ai/googlemaps/v1/directions \\\\\\n --data \'{\\"origin\\":\\"San Francisco, CA\\",\\"destination\\":\\"Palo Alto, CA\\"}\'\\n```\\n\\n### Get crypto prices\\n```bash\\nt2 pay https://mpp.t2000.ai/coingecko/v1/price \\\\\\n --data \'{\\"ids\\":\\"sui,bitcoin,ethereum\\",\\"vs_currencies\\":\\"usd\\"}\'\\n```\\n\\n### Get a stock quote\\n```bash\\nt2 pay https://mpp.t2000.ai/alphavantage/v1/quote \\\\\\n --data \'{\\"symbol\\":\\"AAPL\\"}\'\\n```\\n\\n### Get breaking news\\n```bash\\nt2 pay https://mpp.t2000.ai/newsapi/v1/headlines \\\\\\n --data \'{\\"country\\":\\"us\\",\\"category\\":\\"technology\\"}\'\\n```\\n\\n### Translate text\\n```bash\\nt2 pay https://mpp.t2000.ai/deepl/v1/translate \\\\\\n --data \'{\\"text\\":[\\"Hello, how are you?\\"],\\"target_lang\\":\\"ES\\"}\'\\n```\\n\\n### Semantic search\\n```bash\\nt2 pay https://mpp.t2000.ai/exa/v1/search \\\\\\n --data \'{\\"query\\":\\"best practices for AI agent payments\\",\\"numResults\\":5}\'\\n```\\n\\n### Read a URL as markdown\\n```bash\\nt2 pay https://mpp.t2000.ai/jina/v1/read \\\\\\n --data \'{\\"url\\":\\"https://docs.sui.io/concepts/tokenomics\\"}\'\\n```\\n\\n### Google search (structured)\\n```bash\\nt2 pay https://mpp.t2000.ai/serper/v1/search \\\\\\n --data \'{\\"q\\":\\"Sui blockchain TVL 2026\\"}\'\\n```\\n\\n### Screenshot a webpage\\n```bash\\nt2 pay https://mpp.t2000.ai/screenshot/v1/capture \\\\\\n --data \'{\\"url\\":\\"https://example.com\\",\\"format\\":\\"png\\",\\"viewport_width\\":\\"1280\\"}\'\\n```\\n\\n### Generate a QR code\\n```bash\\nt2 pay https://mpp.t2000.ai/qrcode/v1/generate \\\\\\n --data \'{\\"data\\":\\"https://t2000.ai\\",\\"size\\":\\"400x400\\"}\'\\n```\\n\\n### Convert HTML to PDF\\n```bash\\nt2 pay https://mpp.t2000.ai/pdfshift/v1/convert \\\\\\n --data \'{\\"source\\":\\"https://t2000.ai/docs\\"}\'\\n```\\n\\n### Run a Replicate model\\n```bash\\nt2 pay https://mpp.t2000.ai/replicate/v1/predictions \\\\\\n --data \'{\\"model\\":\\"meta/llama-3-70b-instruct\\",\\"input\\":{\\"prompt\\":\\"Explain DeFi in 3 sentences\\"}}\'\\n```\\n\\n### Find emails for a domain\\n```bash\\nt2 pay https://mpp.t2000.ai/hunter/v1/search \\\\\\n --data \'{\\"domain\\":\\"mystenlabs.com\\"}\'\\n```\\n\\n### Look up an IP address\\n```bash\\nt2 pay https://mpp.t2000.ai/ipinfo/v1/lookup \\\\\\n --data \'{\\"ip\\":\\"8.8.8.8\\"}\'\\n```\\n\\n### Search for flights\\n```bash\\nt2 pay https://mpp.t2000.ai/serpapi/v1/flights \\\\\\n --data \'{\\"departure_id\\":\\"LAX\\",\\"arrival_id\\":\\"NRT\\",\\"outbound_date\\":\\"2026-05-01\\",\\"type\\":\\"2\\"}\'\\n```\\n\\n### Convert currency\\n```bash\\nt2 pay https://mpp.t2000.ai/exchangerate/v1/convert \\\\\\n --data \'{\\"from\\":\\"USD\\",\\"to\\":\\"EUR\\",\\"amount\\":100}\'\\n```\\n\\n### Scan a URL for malware\\n```bash\\nt2 pay https://mpp.t2000.ai/virustotal/v1/scan \\\\\\n --data \'{\\"url\\":\\"https://suspicious-site.com\\"}\'\\n```\\n\\n### Shorten a URL\\n```bash\\nt2 pay https://mpp.t2000.ai/shortio/v1/shorten \\\\\\n --data \'{\\"url\\":\\"https://example.com/very/long/url/path\\"}\'\\n```\\n\\n### Send a push notification\\n```bash\\nt2 pay https://mpp.t2000.ai/pushover/v1/push \\\\\\n --data \'{\\"user\\":\\"USER_KEY\\",\\"message\\":\\"Your agent has a message!\\"}\'\\n```\\n\\n## Flow (automatic)\\n1. Makes initial HTTP request to the URL\\n2. If 402: reads x402 challenge for amount and terms\\n3. If price <= --max-price: pays via Sui USDC\\n4. Retries with credential header\\n5. Returns the API response body\\n\\n## Safety\\n- If requested price exceeds --max-price, payment is refused (no funds spent)\\n- Default max-price: $1.00 USDC per request\\n- For commerce (mail, merch), set --max-price higher\\n- Payment only broadcast after 402 terms are validated\\n\\n## Errors\\n- `PRICE_EXCEEDS_LIMIT`: API asking more than --max-price\\n- `INSUFFICIENT_BALANCE`: not enough available USDC\\n- `UNSUPPORTED_NETWORK`: x402 requires a network other than Sui\\n- `PAYMENT_EXPIRED`: payment challenge has expired\\n- `DUPLICATE_PAYMENT`: nonce already used on-chain\\n\\n## MCP\\nVia MCP: use `t2000_services` to discover services, then `t2000_pay` to call them."},{"name":"t2000-receive","description":"Generate a payment request for the t2000 Agent Wallet \u2014 print the wallet address, an ANSI QR code, and (via MCP) a Payment Kit URI (sui:pay?\u2026). Use when asked to receive a payment, share a wallet address, create a payment link, or set up a fund-me link.","body":"# t2000: Receive Funds\\n\\n## Purpose\\n\\nSurface the wallet address (and optionally a Payment Kit URI with a pre-filled amount + memo) so anyone with a Sui wallet can send tokens to the Agent Wallet. Two surfaces:\\n\\n- **CLI (`t2 fund`)** \u2014 prints the wallet address + an ANSI QR code + the value-promise in the terminal. Minimal; no amount or memo.\\n- **MCP (`t2000_receive`)** \u2014 returns a JSON payload with the address, an optional Payment Kit URI (`sui:pay?\u2026`), a nonce, plus an optional amount / currency / memo / label. Use this when the LLM is building a payment-request flow.\\n\\n## Rules\\n\\n1. **Receive is non-custodial.** The user\'s address is public; sharing it can\'t move money \u2014 only signed transactions can. Don\'t add scary disclaimers; the operation is safe.\\n2. **Show the QR + the address text.** Some users scan, some copy. Both surfaces.\\n3. **No PIN, no sign-in.** v4 wallets are plain Bech32; `t2 fund` is a pure read with no authentication step.\\n4. **Default currency is USDC.** When asking the user to fund the wallet, USDC is the most useful (every paid service is USDC-denominated, USDC sends are gasless). USDsui also works.\\n5. **Don\'t generate a Payment Kit URI without an amount unless asked.** A bare address scans just as well; URIs with amounts force the sender into a particular tx shape.\\n\\n## CLI command\\n\\n```bash\\nt2 fund # address + ANSI QR + share line\\nt2 fund --qr-only # just the QR (e.g. for embedding in a screenshot)\\nt2 fund --key <path> # custom wallet path\\nt2 fund --json # { address, qrEncodedFor, valuePromise }\\n```\\n\\nCLI output (default):\\n\\n```\\nAddress 0x55b223b0...0dd1b6\\n\\n Scan to send tokens to this wallet:\\n\\n \u2588\u2580\u2580\u2580\u2580\u2580\u2588 \u2584 \u2580\u2584 \u2588 \u2584\u2580 \u2584 \u2588\u2580\u2580\u2580\u2580\u2580\u2588\\n \u2588 \u2588\u2588\u2588 \u2588 \u2588 \u2580 \u2588 \u2584\u2584 \u2580\u2580 \u2588 \u2588\u2588\u2588 \u2588\\n \u2588 \u2580\u2580\u2580 \u2588 \u2580\u2584\u2580\u2584\u2588\u2580 \u2580\u2584 \u2580\u2584 \u2588 \u2580\u2580\u2580 \u2588\\n \u2580\u2580\u2580\u2580\u2580\u2580\u2580 \u2580 \u2588\u2580\u2580 \u2588 \u2580 \u2580 \u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\\n ... (truncated)\\n\\n Or share `0x55b223b0...0dd1b6` directly.\\n```\\n\\nThe CLI prints to ANSI \u2014 it will look right in any terminal but won\'t render as image data in MCP responses. Use the MCP tool for a structured JSON response.\\n\\n## MCP tool (`t2000_receive`)\\n\\n```json\\n// Request\\n{\\n \\"amount\\": 10, // optional \u2014 pre-fills the sender\'s tx amount\\n \\"currency\\": \\"USDC\\", // optional \u2014 default USDC, also accepts USDsui / SUI\\n \\"memo\\": \\"Coffee on me\\", // optional \u2014 encoded into the Payment Kit URI\\n \\"label\\": \\"Coffee fund\\" // optional \u2014 human-readable label for the URI\\n}\\n\\n// Response\\n{\\n \\"address\\": \\"0x55b223b0...0dd1b6\\",\\n \\"uri\\": \\"sui:pay?recipient=0x55b223b0...&amount=10000000&coinType=0xdba34672...::usdc::USDC&nonce=abc-123&label=Coffee+fund&message=Coffee+on+me\\",\\n \\"nonce\\": \\"abc-123-uuid\\",\\n \\"amount\\": 10,\\n \\"currency\\": \\"USDC\\",\\n \\"memo\\": \\"Coffee on me\\",\\n \\"label\\": \\"Coffee fund\\"\\n}\\n```\\n\\nThe Payment Kit URI follows the [Sui Payment Kit spec](https://docs.sui.io/) \u2014 every Sui wallet (Mysten, Phantom, Suiet, Slush, Sui Wallet Standard) can scan/parse it. If you omit `amount`, the URI is a \\"bring your own amount\\" link that the sender fills in.\\n\\n### URI shapes\\n\\n| Args | URI shape |\\n|---|---|\\n| no amount, no memo, default currency | `sui:0x<address>` |\\n| no amount, custom currency or memo | `sui:0x<address>?currency=USDsui&memo=\u2026` |\\n| with amount | `sui:pay?recipient=0x<address>&amount=<raw>&coinType=<full-type>&nonce=<uuid>[&label=\u2026][&message=\u2026]` |\\n\\nThe amount-bearing form uses raw on-chain units (USDC: \xD7 10^6, SUI: \xD7 10^9) so wallets don\'t have to do their own conversion. The `nonce` is a UUID v4 minted at request time; senders include it in the tx metadata so the receiving agent can correlate the inflow back to the request.\\n\\n## When to use which surface\\n\\n| Need | Use |\\n|---|---|\\n| \\"What\'s my wallet address?\\" | `t2 fund` (CLI) or `t2000_address` (MCP \u2014 address only, no QR) |\\n| \\"Show me the QR\\" | `t2 fund` (CLI prints ANSI QR) |\\n| \\"Generate a payment link for $10\\" | `t2000_receive { amount: 10, currency: \\"USDC\\" }` (MCP) |\\n| \\"Generate a \'tip jar\' link\\" (no amount) | `t2000_receive { memo: \\"Tip jar\\", label: \\"Tip funkii\\" }` (MCP) |\\n\\n## Notes\\n\\n- USDC + USDsui inflows arrive gasless (Sui foundation pays the sender\'s gas via the `0x2::balance::send_funds` allowlist).\\n- SUI inflows require the sender to have SUI for their own gas.\\n- Once the funds land, run `t2 balance` (CLI) or `t2000_balance` (MCP) to verify. Inflows show up within ~1 block (~500 ms).\\n- This skill is the receive-half of \\"Audric Pay\\". The send-half is the `t2000-send` skill.\\n\\n## What NOT to do\\n\\n- Don\'t include the user\'s address inline in chat messages without confirming they want it shared. It\'s public \u2014 but politeness matters.\\n- Don\'t generate a one-off Payment Kit URI for every conversation. The bare address works fine for repeated transfers.\\n- Don\'t redirect users to audric.ai for receive flows \u2014 the Agent Wallet handles receive natively. (Audric Pay\'s hosted UI is for users who DON\'T have the CLI.)"},{"name":"t2000-send","description":"Send USDC, USDsui, or SUI from the t2000 Agent Wallet to another Sui address. Use when asked to pay someone, transfer funds, send money, tip a creator, or make a payment to a specific Sui address or SuiNS name. Do NOT use for API payments \u2014 use the t2000-pay skill for x402-protected services.","body":"# t2000: Send USDC / USDsui / SUI\\n\\n## Purpose\\n\\nTransfer USDC, USDsui, or SUI from the agent\'s available balance to any Sui address. **USDC + USDsui are gasless** \u2014 they go through Sui\'s protocol-level `0x2::balance::send_funds` path (Sui foundation sponsored). **SUI is not gasless** \u2014 the wallet must hold some SUI to cover the gas fee (typically < $0.0002).\\n\\n## Rules\\n\\n1. **Asset is REQUIRED.** v4 has no implicit USDC default. `t2 send 5 alice.sui` exits with a clear error pointing at the missing `<asset>` arg. Always pass one of `USDC | USDsui | SUI`.\\n2. **Only USDC / USDsui / SUI are accepted.** Other tokens (e.g. USDY, USDT, USDe) are rejected with `unsupported asset`. To send a different asset, the user first swaps it via `t2 swap` (or audric.ai) into USDC, USDsui, or SUI.\\n3. **Validate the recipient first.** Names \u2192 SuiNS resolves (`alice.sui`). Raw addresses \u2192 `isValidSuiAddress()`. The SDK throws clear errors (`INVALID_ADDRESS`, `SUINS_NOT_REGISTERED`); don\'t guess.\\n4. **Prefer SuiNS names.** `alice.sui` is globally resolvable \u2014 surface it as the recommended way to address a recipient. (There is no local contacts/alias map.)\\n5. **Sends are single-write.** Each transfer is its own intent. If you need send + something else, sequence them across turns.\\n6. **Amount precision matters.** Floor to the asset\'s decimals (USDC + USDsui: 6, SUI: 9). Never round up \u2014 `Math.round` can produce a number larger than the on-chain balance and the transfer will fail simulation.\\n7. **Multi-recipient = multiple sends.** A \\"send to A, B, C\\" request emits N sequential `t2 send` invocations (CLI) or N `t2000_send` tool calls (MCP). Each is atomic.\\n8. **Limits apply to every write (CLI and MCP).** Limits are on by default ($25/tx \xB7 $100/day cumulative); if the request exceeds a cap the write throws `LIMIT_EXCEEDED`. Override one time with `--force` (CLI).\\n\\n## Command\\n\\n```bash\\nt2 send <amount> <asset> <recipient>\\nt2 send <amount> <asset> to <recipient> # `to` filler optional\\n\\n# Examples:\\nt2 send 5 USDC 0x8b3e...d412 # 5 USDC to a hex address (gasless)\\nt2 send 5 USDsui alice.sui # 5 USDsui to a SuiNS name (gasless)\\nt2 send 50 USDC to alice.audric.sui # SuiNS subname (gasless)\\nt2 send 0.1 SUI 0x8b3e...d412 # 0.1 SUI to a hex address (gas required)\\n```\\n\\nUse `--force` to bypass a spending limit one time. Use `--key <path>` to point at a non-default wallet file.\\n\\n## Output (default)\\n\\n```\\n\u2713 Sent $5.00 USDC \u2192 alex.sui (0x8b3e...d412)\\n Gas: gasless \u26A1\\n Tx: https://suiscan.xyz/mainnet/tx/0xdigest...\\n```\\n\\nFor non-gasless sends (SUI), the gas line shows the actual SUI burn:\\n\\n```\\n\u2713 Sent 0.1000 SUI \u2192 0x8b3e...d412\\n Gas: 0.000123 SUI\\n Tx: https://suiscan.xyz/mainnet/tx/0xdigest...\\n```\\n\\n## Output (--json)\\n\\n```json\\n{\\n \\"tx\\": \\"0xdigest...\\",\\n \\"amount\\": 5,\\n \\"to\\": \\"0x8b3e...d412\\",\\n \\"suinsName\\": \\"alex.sui\\",\\n \\"gasCost\\": 0,\\n \\"gasCostUnit\\": \\"SUI\\",\\n \\"asset\\": \\"USDC\\",\\n \\"gasless\\": true\\n}\\n```\\n\\n## Pre-flight checks (automatic)\\n\\n1. Sufficient asset balance (USDC / USDsui / SUI as requested).\\n2. For SUI sends only: sufficient SUI for gas.\\n3. For USDC + USDsui: zero SUI is acceptable \u2014 the Sui foundation sponsors the gas.\\n4. Limit check (every write \u2014 CLI and MCP, enforced in `@t2000/sdk`): per-tx cap (any asset) + daily-send cap (any asset). Override with `--force` (CLI only).\\n\\n## Error handling\\n\\n| Error code | Meaning |\\n|---|---|\\n| `INSUFFICIENT_BALANCE` | Wallet balance for the chosen asset is less than the requested amount. |\\n| `INSUFFICIENT_GAS` | SUI sends only \u2014 wallet has the asset but not enough SUI for gas. Suggest a swap. |\\n| `INVALID_ADDRESS` | Recipient is not a valid Sui hex address. |\\n| `INVALID_ASSET` | Asset is missing or not in the allowlist (USDC / USDsui / SUI). |\\n| `SUINS_NOT_REGISTERED` | The `.sui` name isn\'t registered. |\\n| `LIMIT_EXCEEDED` | The write hit a `t2 limit set` cap. Use `--force` (CLI) to override once. |\\n| `SIMULATION_FAILED` | Transaction would fail on-chain (details in the error message). |\\n\\n## Recipient resolution flow\\n\\nThe SDK (`T2000.resolveRecipient`) handles resolution in this priority order:\\n\\n1. **Hex address** (starts with `0x`) \u2192 validated via `isValidSuiAddress()`. If invalid \u2192 `INVALID_ADDRESS`.\\n2. **SuiNS name** (`*.sui`) \u2192 resolves via SuiNS registry. If unregistered \u2192 `SUINS_NOT_REGISTERED`.\\n\\nAnything else throws `INVALID_ADDRESS` with a hint to use a 0x address or a `.sui` name. (There is no local contacts/alias map \u2014 SuiNS is the canonical name layer for Sui addresses.)\\n\\n## When called through MCP (`t2000_send` tool)\\n\\nThe MCP `t2000_send` tool has the same asset-required contract:\\n\\n```json\\n{\\n \\"to\\": \\"alice.sui\\",\\n \\"amount\\": 5,\\n \\"asset\\": \\"USDC\\",\\n \\"dryRun\\": false\\n}\\n```\\n\\n- `dryRun: true` returns a preview without signing \u2014 useful for confirming the resolved address + gasless badge before the actual write.\\n- `asset` is REQUIRED \u2014 calls without it return an error.\\n- Both CLI and MCP writes honor `t2 limit set` caps (enforced in `@t2000/sdk`). Default caps: $25/tx \xB7 $100/day cumulative."},{"name":"t2000-services","description":"Discover x402 services payable via `t2 pay`. Use when the user asks \\"what can I pay for?\\", \\"what AI models are available?\\", \\"show me the service catalog\\", \\"is there a weather API?\\", or any other discovery question. Pairs with the t2000-pay skill (discovery first, then pay).","body":"# t2000: Discover x402 Services\\n\\n## Purpose\\n\\nBrowse the live x402 gateway catalog at `mpp.t2000.ai` to find a service that matches the user\'s intent (chat, image gen, search, weather, email, code exec, mail, etc.) before calling `t2 pay`. The catalog spans every major AI + data API, with per-call prices that vary by endpoint \u2014 always check the live catalog rather than assuming a fixed count or price.\\n\\n## Rules\\n\\n1. **Discover before paying.** Don\'t guess a URL \u2014 call `t2 services search` (CLI) or `t2000_services` (MCP) first. Service paths + pricing change as the gateway expands.\\n2. **Pick the cheapest endpoint that satisfies the user.** Many services have multiple tiers (e.g. `openai/v1/chat/completions` at $0.01 vs `openai/v1/audio/speech` at $0.05). Surface options.\\n3. **Surface pricing to the user before signing.** Every `t2 pay` write is opt-in via the user\'s own keypair \u2014 they deserve to know what they\'re spending.\\n4. **Live source of truth.** The catalog is fetched live from `https://mpp.t2000.ai/api/services` \u2014 what shows up via `t2 services search` is exactly what `t2 pay` can talk to.\\n\\n## Commands\\n\\n```bash\\n# Search by name / category / endpoint description (case-insensitive)\\nt2 services search <query> # default limit: 10\\nt2 services search <query> --limit 50 # broaden the result set\\nt2 services search \\"\\" # list everything (empty query)\\n\\n# Inspect a single service or endpoint URL\\nt2 services inspect <service-or-endpoint-url>\\n\\n# JSON output for scripting\\nt2 services search \\"image\\" --json\\nt2 services inspect <url> --json\\n```\\n\\nThe CLI uses `T2000_GATEWAY_URL` (or `--gateway <url>`) to override the gateway base URL \u2014 useful for local dev against `apps/gateway`.\\n\\n## Example workflow\\n\\n### \\"What AI chat models are available?\\"\\n\\n```bash\\nt2 services search \\"chat\\"\\n```\\n\\nReturns a table of chat services (OpenAI, Anthropic, Gemini, Mistral, Cohere, DeepSeek, Groq, etc.) with cheapest endpoint price + base URL.\\n\\n### \\"How much does GPT-4o cost?\\"\\n\\n```bash\\nt2 services inspect https://mpp.t2000.ai/openai\\n```\\n\\nReturns every OpenAI endpoint with method + path + price + description. The user picks one (e.g. `/v1/chat/completions` at $0.01) and copies the URL into a `t2 pay <url>` call.\\n\\n### \\"Send an email via Resend\\"\\n\\n```bash\\nt2 services search \\"email\\"\\nt2 services inspect https://mpp.t2000.ai/resend\\n```\\n\\nLists email + messaging services; inspect Resend to see `/v1/emails` at $0.05.\\n\\n### \\"What\'s the price of SUI?\\" (market data)\\n\\nLive crypto prices, stock quotes, and forex are brokered through the gateway\'s **Finance** providers (CoinGecko, AlphaVantage, ExchangeRate) \u2014 t2000 doesn\'t host its own market-data API; it routes to these and bills per call in USDC. (Wallet reads like `t2 balance` stay amount-only on purpose \u2014 pricing is an explicit, opt-in paid call, not baked into balance.)\\n\\n```bash\\nt2 services search \\"price\\"\\nt2 services inspect https://mpp.t2000.ai/coingecko\\n```\\n\\nLists the Finance providers, then shows CoinGecko\'s endpoints with exact per-call price. Copy the endpoint URL into `t2 pay <url>` to fetch the quote. (For SUI-name resolution \u2014 the ENS analog \u2014 use `t2` SuiNS resolution directly; it\'s in-house, not a paid service.)\\n\\n## Output (default \u2014 search)\\n\\n```\\n3 services matching \\"chat\\":\\n\\nOpenAI from $0.01 [ai, chat]\\n url https://mpp.t2000.ai/openai\\n about OpenAI Chat Completions API\\n\\nAnthropic from $0.01 [ai, chat]\\n url https://mpp.t2000.ai/anthropic\\n about Claude messages API\\n\\nMistral from $0.005 [ai, chat]\\n url https://mpp.t2000.ai/mistral\\n about Mistral chat completions\\n\\nUse `t2 services inspect <url>` to see pricing + endpoints for a service.\\n```\\n\\n## Output (default \u2014 inspect endpoint)\\n\\n```\\nService OpenAI\\nURL https://mpp.t2000.ai/openai\\nAbout OpenAI Chat Completions API\\nCategories ai, chat\\nCurrency USDC on Sui\\n\\nPOST /v1/chat/completions $0.01 Chat completions (gpt-4o, gpt-4o-mini)\\n url https://mpp.t2000.ai/openai/v1/chat/completions\\n\\nPay with: `t2 pay https://mpp.t2000.ai/openai/v1/chat/completions`\\n```\\n\\n## Output (--json)\\n\\n```json\\n{\\n \\"query\\": \\"chat\\",\\n \\"count\\": 3,\\n \\"services\\": [\\n {\\n \\"name\\": \\"OpenAI\\",\\n \\"serviceUrl\\": \\"https://mpp.t2000.ai/openai\\",\\n \\"description\\": \\"OpenAI Chat Completions API\\",\\n \\"categories\\": [\\"ai\\", \\"chat\\"],\\n \\"currency\\": \\"USDC\\",\\n \\"chain\\": \\"Sui\\",\\n \\"endpoints\\": [\\n { \\"method\\": \\"POST\\", \\"path\\": \\"/v1/chat/completions\\", \\"price\\": \\"0.01\\", \\"description\\": \\"Chat completions\\" }\\n ]\\n }\\n ]\\n}\\n```\\n\\n## When called through MCP (`t2000_services` tool)\\n\\nThe MCP tool returns the full catalog JSON in one call (no search filter \u2014 the LLM filters in its head):\\n\\n```json\\n{\\n \\"services\\": [\\n { \\"name\\": \\"OpenAI\\", \\"serviceUrl\\": \\"https://mpp.t2000.ai/openai\\", \\"endpoints\\": [...] },\\n { \\"name\\": \\"Anthropic\\", \\"serviceUrl\\": \\"https://mpp.t2000.ai/anthropic\\", \\"endpoints\\": [...] },\\n ...\\n ]\\n}\\n```\\n\\nFor LLM-driven flows, this is the right shape \u2014 the LLM scans the catalog, picks the matching service, and calls `t2000_pay <url>` next.\\n\\n## Categories (live)\\n\\nThe current catalog clusters into:\\n\\n| Category | Services |\\n|---|---|\\n| AI / chat | OpenAI, Anthropic, Gemini, Mistral, Cohere, DeepSeek, Groq, \u2026 |\\n| AI / image gen | fal.ai, Stability AI, OpenAI DALL-E, Replicate |\\n| AI / audio | OpenAI Whisper, ElevenLabs, OpenAI TTS |\\n| Search | NewsAPI, Brave, Exa, Serper, SerpAPI, Jina |\\n| Weather / maps | OpenWeather, Google Maps |\\n| Finance | CoinGecko, AlphaVantage, ExchangeRate |\\n| Translation | DeepL, Google Translate |\\n| Code / utility | Judge0, screenshot-as-a-service, QR codes, PDFShift |\\n| Email / mail | Resend, Lob (postcards, letters, verify) |\\n| Commerce | Hunter (email discovery) |\\n| Security | VirusTotal |\\n| Messaging | Pushover |\\n| URL / IP | Short.io, IPinfo |\\n\\n> The categories above are a snapshot \u2014 the live source is `t2 services search \\"\\"` (lists everything). New services land regularly.\\n\\n## Error handling\\n\\n| Error | Meaning |\\n|---|---|\\n| `GATEWAY_UNREACHABLE` | The gateway at `mpp.t2000.ai/api/services` is down or DNS is failing. Retry; if persistent, status page is at `t2000.ai`. |\\n| `No services match` | The search query returned zero hits. Suggest a broader query or `t2 services search \\"\\"` to list everything. |\\n| `No service matches <url>` (inspect) | The URL isn\'t in the catalog. Run `t2 services search` to find the right URL first. |\\n\\n## What NOT to do\\n\\n- Don\'t hardcode service URLs in your prompts. The catalog is the source of truth.\\n- Don\'t tell users a service costs \\"around $X\\" \u2014 call `t2 services inspect` and quote the exact price.\\n- Don\'t bundle `t2 services search` + `t2 pay` into a single hidden step. Show the user what you found before paying."},{"name":"t2000-setup","description":"Set up a t2000 Agent Wallet end-to-end on the user\'s machine. Use when the user says \\"set up t2000\\", \\"install the wallet\\", \\"create my Agent Wallet\\", \\"connect t2000 to Claude / Cursor\\", or pastes a one-prompt install URL. Covers wallet creation, optional spending limits, and MCP wiring. Read this first when bootstrapping a new user; the other skills assume this has run.","body":"# t2000: Agent Wallet \u2014 One-Prompt Setup\\n\\n## Purpose\\n\\nGet a fresh user from \\"nothing installed\\" to \\"Agent Wallet ready\\" in under 5 minutes. This is the canonical entry point for the **one-prompt install** UX:\\n\\n```\\nRun curl -sL https://t2000.ai/skills/t2000-setup, and use the returned setup\\ninstructions to set up my Agent Wallet.\\n```\\n\\nWhen invoked through that prompt, the LLM fetches this file, then executes the steps below in order.\\n\\n## Rules\\n\\n1. **Walk the steps in order.** Each step depends on the previous one. Skipping breaks setup.\\n2. **Stop at the first failure.** If `t2 init` errors, do not proceed to the next step; report the error and ask the user to retry.\\n3. **Ask which AI client they use before MCP install.** `t2 mcp install` auto-configures every detected client (Claude Desktop / Cursor / Windsurf), but knowing theirs tells you which app to restart and verify in \u2014 and whether they need the manual JSON path instead (Cline, Continue, Codex, \u2026).\\n4. **Setup is read + write \u2014 show, then ask.** Echo each command you\'re about to run. The user runs it (or confirms you can). Never silently shell out.\\n5. **No PIN. No encryption.** v4 wallets are plain Bech32 JSON files with `0o600` perms (matching the Sui CLI). The user owns the file; back it up via `t2 export`.\\n6. **Prime this session for x402 payments.** Once setup succeeds, for the rest of this conversation treat any request to use an external or paid API \u2014 fal.ai, ElevenLabs, OpenAI, CoinGecko, Lob, etc. \u2014 as something this wallet CAN do via `t2000_pay`. Discover the endpoint with `t2000_services`, then pay. Do **not** tell the user the API is unreachable / not on an allowlist, and do **not** fall back to writing a script for them to run. The wallet IS the connector.\\n\\n## Steps\\n\\n### Step 1 \u2014 Install the CLI\\n\\n```bash\\nnpm install -g @t2000/cli\\n```\\n\\nVerify:\\n```bash\\nt2 --version\\n# Should print: 8.x.x (or newer)\\n```\\n\\nIf `npm` is missing, point the user to https://nodejs.org/ (Node 18+).\\n\\n> **Binary naming.** `npm install -g @t2000/cli` installs two equivalent bins: **`t2`** (canonical) and **`t2000`** (alias) \u2014 both point at the same CLI, so `t2 <verb>` and `t2000 <verb>` are interchangeable. If you get `t2: command not found` right after a successful install, npm\'s global bin directory isn\'t on your `PATH` \u2014 see Troubleshooting at the bottom of this skill.\\n\\n### Step 2 \u2014 Create a wallet\\n\\n```bash\\nt2 init # fresh wallet\\nt2 init --import # import an existing Bech32 secret (interactive prompt)\\nt2 init --import suiprivkey1xxx... # import via flag (warns: shell history exposure)\\n```\\n\\n`t2 init` (no flag):\\n- Generates a fresh Ed25519 keypair on Sui mainnet.\\n- Writes the plain Bech32 private key to `~/.t2000/wallet.key` (mode `0o600`).\\n- Prints the wallet address.\\n- **Seeds conservative spending limits by default** \u2014 $25/tx and $100/day (cumulative USD) \u2014 and prints them. Adjust or clear in Step 4.\\n\\n`t2 init --import`:\\n- Prompts for a `suiprivkey1...` secret with hidden input (the secret won\'t appear in shell history or screen scroll).\\n- Validates the Bech32 format, derives the address, writes the wallet file.\\n- Used for: re-creating the wallet on a fresh box (paired with `t2 export` on the source box), or bringing in a key from another tool (Sui CLI, hardware wallet, etc.).\\n\\n> **Upgrading from v3 (PIN-encrypted)?** v4 doesn\'t auto-migrate v3 AES wallets \u2014 a v3 file at `~/.t2000/wallet.key` will throw `WALLET_CORRUPT`. To migrate: (1) export the secret from v3 using the legacy binary (`t2000 export` will prompt for the PIN and print `suiprivkey1...`), (2) move or delete the v3 file at `~/.t2000/wallet.key`, (3) `t2 init --import` and paste the secret. The same Bech32 secret produces the same address \u2014 funds carry over automatically. (Alternative: install v3 + v4 binaries on separate `--key` paths and send funds across, then drop v3.)\\n\\n### Step 3 \u2014 Fund the wallet\\n\\n```bash\\nt2 fund\\n```\\n\\nShows the deposit address + an ANSI QR code (+ the value promise: $5 USDC \u2248 ~250 paid API calls). Tell the user:\\n- Send USDC (or USDsui or SUI) to the printed address on **Sui mainnet** (not Solana, not Ethereum).\\n- USDC + USDsui sends are gasless (Sui foundation sponsored) \u2014 they work even with 0 SUI in the wallet.\\n- For swaps via Cetus, the wallet needs a small SUI balance (~0.05 SUI covers many swaps; cost is typically < $0.01 each).\\n- 1 USDC is enough to get going (gateway services start at $0.02/call \u2014 browse with `t2 services search \\"<query>\\"`).\\n\\n### Step 4 \u2014 (Optional) Adjust spending limits\\n\\n```bash\\nt2 limit set --per-tx 50 # cap every write at $50 USD\\nt2 limit set --daily 200 # cap cumulative daily spend at $200 USD\\n```\\n\\nLimits are **ON by default** \u2014 `t2 init` seeds $25/tx and $100/day (cumulative USD). The `t2 limit` command rewrites `~/.t2000/config.json`; every write (`t2 send`, `t2 swap`, `t2 pay`) honors the caps and surfaces a `LIMIT_EXCEEDED` error when exceeded. Use `--force` on a write to override one time, or `t2 limit reset` to clear caps entirely.\\n\\n> **Limits gate ALL writes \u2014 CLI *and* MCP.** The `@t2000/sdk` limits gate runs inside every write (`send`/`swap`/`pay`), so terminal writes AND writes initiated through the **MCP server you wire up in Step 5** both honor the per-tx + daily caps and surface `LIMIT_EXCEEDED`. (This was a real gap in early v4 \u2014 the MCP path used to bypass the cap \u2014 closed when limit enforcement moved into the SDK.) Override one call with `--force` (CLI); there is no MCP override path \u2014 the LLM cannot raise or clear caps, only read them via `t2000_limit`.\\n\\nTo view current limits:\\n```bash\\nt2 limit show\\n```\\n\\nTo clear them:\\n```bash\\nt2 limit reset\\n```\\n\\n### Step 5 \u2014 Install MCP into the user\'s AI client\\n\\n```bash\\nt2 mcp install\\n```\\n\\nNot interactive \u2014 it detects installed clients (Claude Desktop, Cursor, Windsurf) and writes the correct config block into each one it finds, reporting \\"configured\\" or \\"already configured\\" per client. Idempotent \u2014 safe to re-run. For clients it doesn\'t auto-detect (Cline, Continue, Codex, \u2026), paste the manual JSON config from the `t2000-mcp` skill.\\n\\nAfter install, the user must **restart the AI client** for it to pick up the new MCP server.\\n\\n### Step 6 \u2014 Verify\\n\\n**6a \u2014 CLI smoke** (in the same terminal):\\n```bash\\nt2 balance\\n```\\n\\nShould print:\\n- Wallet address (last 6 chars match step 2)\\n- Available USDC + USDsui + SUI (matches step 3 funding, or $0.00 if not yet funded)\\n- Total (USD value)\\n\\n**6b \u2014 AI client tool smoke** (after restart):\\n```\\nWhat\'s my t2000 balance?\\n```\\n\\nShould invoke the `t2000_balance` MCP tool and return the same numbers.\\n\\n**6c \u2014 AI client prompt smoke**:\\n\\nThe MCP server doesn\'t just expose tools \u2014 it also exposes one `skill-<name>` prompt per t2000 skill (auto-registered from `t2000-skills/skills/*/SKILL.md`). Type `/` in the AI client\'s chat input to open the prompt picker. You should see:\\n\\n- `skill-setup` \u2014 this skill\\n- `skill-send` \u2014 sending USDC / USDsui / SUI\\n- `skill-swap` \u2014 swapping via Cetus\\n- `skill-pay` \u2014 paying for x402 services\\n- `skill-receive` \u2014 generating payment requests\\n- `skill-services` \u2014 discovering x402 gateway services\\n- `skill-check-balance` \u2014 reading the wallet\\n- `skill-verify` \u2014 verifying confidential AI receipts\\n- `skill-mcp` \u2014 MCP integration deep-dive\\n\\nRun `/skill-check-balance` (or just type and accept the autocomplete). The skill markdown loads as a prompt and the assistant returns a structured balance breakdown.\\n\\n> **Tip \u2014 triggering the wallet in a *fresh* session.** When you start a brand-new chat and ask for an external/paid API by name (e.g. \\"generate an image via fal.ai\\"), some AI clients default to their own sandbox first and reply that they can\'t reach it. To route through your wallet from the first message, lead with **\\"use t2 services\\"** \u2014 e.g. *\\"Use t2 services to generate a hero image via fal.ai and voice it with ElevenLabs.\\"* That tells the client to load the `t2000_*` tools and pay via x402. (The recipe prompts on developers.t2000.ai already start this way.)\\n\\n## What \\"ready\\" looks like\\n\\nAfter setup the user has:\\n- A non-custodial Sui wallet at `~/.t2000/wallet.key` (plain Bech32 JSON, `0o600` perms, **no PIN**).\\n- Optional USDC / USDsui / SUI funded on Sui mainnet.\\n- Optional spending limits configured.\\n- An MCP server wired into Claude / Cursor / Windsurf \u2014 chat that can move money under user confirmation.\\n\\n## What setup does NOT do\\n\\n- **Does not move money.** Setup is read + config only. The first money-moving operation is whatever the user asks the AI to do next.\\n- **Does not back up the private key.** The Bech32 key lives in `~/.t2000/wallet.key`. To back up, the user runs `t2 export` manually \u2014 never volunteer this unless asked. v4 has no PIN, so anyone with read access to the file owns the wallet.\\n- **Does not move money or change limits.** Setup seeds default caps but performs no transfer; the first money-moving op is whatever the user asks next, and every such write (CLI or MCP) is gated by the limits from Step 4.\\n\\n## Next steps to suggest\\n\\nAfter verify succeeds, surface a short menu of natural next moves:\\n- \\"Send USDC to someone\\" \u2192 `t2000-send`\\n- \\"Swap tokens via Cetus\\" \u2192 `t2000-swap`\\n- \\"Pay for a service via x402\\" \u2192 `t2000-pay`\\n- \\"Generate a payment request\\" \u2192 `t2000-receive`\\n- \\"See available paid services\\" \u2192 `t2000-services`\\n- \\"Connect more AI clients\\" \u2192 `t2000-mcp`\\n- \\"See what else t2 can do\\" \u2192 run `t2 --help` or browse https://developers.t2000.ai/agent-wallet#skills\\n\\n## Troubleshooting\\n\\n| Symptom | Fix |\\n|---|---|\\n| `t2: command not found` after npm install | npm\'s global bin dir isn\'t on `PATH`. Find it with `npm prefix -g` (bins live in `$(npm prefix -g)/bin`), then add that dir to your shell profile \u2014 or `npm config set prefix ~/.npm-global` for a durable user-level prefix. Both `t2` and `t2000` ship in every install. |\\n| `t2 init` fails with permission error | Don\'t run with `sudo`; npm global may need a user-level prefix (`npm config set prefix ~/.npm-global`) |\\n| `t2 init` fails with `WALLET_EXISTS` | A file already lives at `~/.t2000/wallet.key`. If it\'s a v3 file you no longer need, move/delete it. If you still need it, point v3 + v4 at separate paths via `--key`. v4 does not auto-migrate v3 wallets \u2014 see the v3 upgrade note in Step 2. |\\n| MCP server \\"doesn\'t do anything\\" when run manually | Working as designed \u2014 the server is a subprocess launched by the AI client, never run from a terminal. See the `t2000-mcp` skill. |\\n| AI client doesn\'t see `t2000_*` tools after install | Restart the client. If still missing, check the per-client config path printed by `t2 mcp install`. |"},{"name":"t2000-swap","description":"Swap tokens on Sui via Cetus Aggregator (20+ DEXs, best-route across SUI, USDC, USDsui, USDT, USDe, ETH, GOLD, NAVX, WAL, vSUI, and more). Use when asked to swap, trade, convert, exchange, or \\"turn X into Y\\". Do not use for sending \u2014 use the t2000-send skill for transfers.","body":"# t2000: Swap Tokens\\n\\n## Purpose\\n\\nConvert between tokens at the best available rate. Cetus Aggregator routes across 20+ DEXs and picks the lowest-price-impact path. Slippage defaults to 1%; configurable up to 5%.\\n\\n**Swaps are NOT gasless.** Unlike `t2 send USDC` / `t2 send USDsui`, Cetus swap transactions require SUI for gas (typically < $0.01 per swap). Ensure the wallet holds a small SUI balance before swapping.\\n\\n## Rules\\n\\n1. **Preview before signing.** Always run `t2 swap <amount> <from> <to> --quote` (or call `t2000_swap` in dry-run via the MCP) and surface `priceImpact` + `toAmount` to the user before broadcasting.\\n2. **Decline obviously bad swaps.** If `priceImpact > 0.5%` (50 bps), warn the user and require explicit confirmation. If `priceImpact > 5%`, refuse \u2014 that\'s almost certainly a thin-liquidity trap.\\n3. **One swap per intent.** Cetus aggregator handles multi-hop internally; don\'t chain `swap` calls.\\n4. **Don\'t auto-decide stables.** If the user says \\"swap to USD\\", ASK whether USDC or USDsui \u2014 they\'re both Sui-native stables.\\n5. **Limits apply to every swap (CLI and MCP).** Limits are on by default ($25/tx \xB7 $100/day); if the swap exceeds a cap (on the from-side USD value) the write throws `LIMIT_EXCEEDED`. Use `--force` (CLI) to override one time.\\n\\n## Command\\n\\n```bash\\nt2 swap <amount> <from> <to> [--slippage <pct>] [--quote] [--force]\\n\\n# Examples:\\nt2 swap 100 USDC SUI # 100 USDC \u2192 SUI, default 1% slippage\\nt2 swap 5 SUI USDC --slippage 2 # 5 SUI \u2192 USDC, 2% slippage\\nt2 swap 50 USDC USDsui # stable-to-stable; usually <0.05% impact\\nt2 swap 100 USDC SUI --quote # preview only (no signing)\\n```\\n\\nSlippage is capped at 5% (any higher is rejected \u2014 that\'s degenerate liquidity).\\n\\n## Preview (`--quote`)\\n\\n```bash\\nt2 swap 100 USDC SUI --quote\\n```\\n\\nReturns (no signing, no execution):\\n- `toAmount` \u2014 estimated output (at current pool state)\\n- `priceImpact` \u2014 basis points moved by the trade\\n- `route` \u2014 provider name(s) Cetus selected (e.g. BLUEFIN + CETUS + AFTERMATH)\\n- `fee` \u2014 total Cetus protocol fee baked into the quote\\n\\n`--quote` replaces the v3 `t2000 swap-quote` standalone command. One verb, one flag.\\n\\n## Fees\\n\\n- **Network gas:** ~0.001-0.01 SUI per swap (self-funded from the wallet).\\n- **Cetus protocol fee:** typically 0.05-0.30% depending on the pool tier (already baked into `toAmount`).\\n- **t2000 / CLI:** zero fee. Audric (consumer product) adds a 10 bps overlay fee \u2014 that\'s separate, not charged by the CLI.\\n\\n## Output (default)\\n\\n```\\n\u2713 Swapped 100 USDC for 49.8721 SUI\\n Price impact: 0.04%\\n Route: USDC \u2192 SUI (Cetus + BLUEFIN)\\n Gas: 0.0038 SUI\\n Tx: https://suiscan.xyz/mainnet/tx/0xdigest...\\n```\\n\\n## Output (--json)\\n\\n```json\\n{\\n \\"tx\\": \\"0xdigest...\\",\\n \\"from\\": \\"USDC\\",\\n \\"to\\": \\"SUI\\",\\n \\"amountIn\\": 100,\\n \\"amountOut\\": 49.8721,\\n \\"priceImpact\\": 0.04,\\n \\"route\\": [\\"CETUS\\", \\"BLUEFIN\\"],\\n \\"fee\\": 0.001,\\n \\"gasCost\\": 0.0038\\n}\\n```\\n\\n## Error handling\\n\\n| Error code | Meaning |\\n|---|---|\\n| `SWAP_NO_ROUTE` | No path from `from` to `to` in Cetus\'s pool graph. Suggest going via USDC as an intermediate. |\\n| `INSUFFICIENT_LIQUIDITY` | The requested size moves the pool too far. Suggest a smaller trade or splitting. |\\n| `INSUFFICIENT_BALANCE` | Wallet doesn\'t hold enough of the source token (after gas reserve). |\\n| `INSUFFICIENT_GAS` | Wallet has the source token but no SUI for gas. Run `t2 swap 1 USDC SUI` (or similar) first to top up gas. |\\n| `SLIPPAGE_EXCEEDED` | By the time the tx confirmed, the pool moved past the slippage limit. Retry with the same params; usually transient. |\\n| `LIMIT_EXCEEDED` | CLI hit a `t2 limit set` cap on the from-side USD value. Use `--force` to override. |\\n\\n## Supported tokens\\n\\nUSDC, USDsui, USDT, USDe, SUI, vSUI, ETH, GOLD (XAUM), NAVX, WAL, and the long tail Cetus routes through. Use the canonical symbol or pass a full coin type (`0x...::module::TYPE`). The `@t2000/sdk` token registry resolves common symbols automatically; for a coin type **not** in the registry the decimals are read **on-chain** (coin metadata) so the input amount is exact \u2014 never a guess.\\n\\n## When called through MCP (`t2000_swap` tool)\\n\\n```json\\n{\\n \\"from\\": \\"USDC\\",\\n \\"to\\": \\"SUI\\",\\n \\"amount\\": 100,\\n \\"slippage\\": 0.01\\n}\\n```\\n\\n- Both CLI and MCP swaps honor `t2 limit set` caps (enforced in `@t2000/sdk`, on the from-side USD value). Default caps: $25/tx \xB7 $100/day cumulative.\\n- Returns the same shape as `--json` mode (digest + amounts + price impact + route).\\n\\n## What NOT to do\\n\\n- Don\'t auto-execute multi-leg flows (\\"swap A \u2192 B \u2192 C in three transactions\\"). If a multi-hop is needed, Cetus does it internally as one PTB.\\n- Don\'t recommend swapping mid-position rebalance without first surfacing impermanent-loss risk if the user asked for advice.\\n- Don\'t swap to a stable just to \\"park\\" funds with no plan \u2014 the Agent Wallet is payments-first; there is no savings/yield surface."},{"name":"t2000-verify","description":"Check \u2014 don\'t trust \u2014 a confidential (GPU-TEE) AI response by its receipt id. Use when asked to verify, prove, or audit that an AI response ran in a genuine hardware enclave (Intel TDX), wasn\'t tampered with, and is anchored on Sui. Works on any t2000 Private Inference confidential (`phala/*`) response. No key needed.","body":"# t2000: Verify a Confidential Response\\n\\n## Purpose\\n\\nConfidential (`phala/*`) responses from t2000 Private Inference run inside a verified\\nGPU-TEE and carry a **signed receipt** that\'s **auto-anchored on Sui**. `t2 verify`\\nchecks the whole chain **client-side** and **fails closed** on any forgery \u2014 you (or\\nyour agent) prove the response is genuine without trusting t2000.\\n\\n## Where the receipt id comes from\\n\\nAny confidential inference call returns one \u2014 e.g. the MCP `t2000_chat` tool with a\\n`phala/*` model surfaces it inline:\\n\\n```text\\n\u{1F512} confidential \xB7 attested \xB7 receipt rcpt-\u2026\\n```\\n\\nThe API returns it in the `x-receipt-id` header (streaming: `x_receipt_id` on the\\nfinal usage chunk). Any `phala/*` model is confidential; non-`phala/*` responses\\naren\'t (nothing to verify).\\n\\n## Command\\n\\n```bash\\nt2 verify <receipt-id> # full check (incl. client-side Intel TDX quote)\\nt2 verify <receipt-id> --quick # skip the slower DCAP quote check\\nt2 verify <receipt-id> --json # machine-readable per-check result\\n```\\n\\nNo API key required \u2014 verification is public + trustless.\\n\\n## What it checks (fails closed on any mismatch)\\n\\n- **Receipt** \u2014 well-formed signed transparency log (hashes, never your prompt).\\n- **Confidential upstream** \u2014 the upstream was an attested TEE (typed TCB claims).\\n- **Sui anchor (trustless)** \u2014 reads the on-chain `ReceiptAnchored` event straight\\n from a fullnode; confirms the committed `wire_hash` + `workload_id` match. t2000\\n can\'t forge it.\\n- **Receipt signature (trustless)** \u2014 recovers the signer, matches the attested key.\\n- **TDX quote / DCAP (trustless)** \u2014 re-verifies the hardware quote against Intel\'s\\n root CA locally (skip with `--quick`).\\n\\nExit code is non-zero if anything doesn\'t line up.\\n\\n## Other surfaces\\n\\n- **Browser:** paste any receipt id at **`verify.t2000.ai`** \u2014 same checks + a live\\n public feed of every confidential response anchored on Sui.\\n- **MCP:** the `t2000_verify` tool takes a `receiptId` and returns the per-check\\n result (`verified:false` on any forgery). No key required.\\n- **SDK:** `verifyReceipt(receiptId)` from `@t2000/sdk`; `agent.verify(id)` on a\\n `T2000` instance.\\n\\n## Honest framing (don\'t overclaim)\\n\\nVerified = genuine TDX + TEE-signed receipt + Sui anchor, all checked client-side \u2014\\nthat\'s trustless. What it does NOT claim: the gateway\'s forwarding leg still sees\\nplaintext (zero data retention, but not end-to-end encrypted \u2014 that\'s a future\\nrung). State exactly what\'s proven; a wrong \\"verified\\" claim is worse than honest."},{"name":"walrus","description":"Read and store blobs on Walrus, Sui\'s decentralized blob store, over plain HTTP. Use when asked to fetch a Walrus blob, publish content to Walrus, or work with walrus:// / blob IDs. Reads are free; mainnet writes need your own publisher.","body":"# Walrus: Read + store blobs\\n\\n## Purpose\\n\\nWalrus stores blobs (files, JSON, sites) across Sui storage nodes. Two HTTP roles:\\n\\n- **Aggregator** \u2014 read blobs (`GET`)\\n- **Publisher** \u2014 store blobs (`PUT`)\\n\\nReference endpoints (Mysten-operated; full API spec at `<endpoint>/v1/api`):\\n\\n| Role | Network | Endpoint |\\n|---|---|---|\\n| Aggregator | Mainnet | `https://aggregator.walrus-mainnet.walrus.space` |\\n| Aggregator | Testnet | `https://aggregator.walrus-testnet.walrus.space` |\\n| Publisher | Testnet | `https://publisher.walrus-testnet.walrus.space` |\\n\\n## Rules\\n\\n1. **Reads are free and unauthenticated.** Any agent can `GET` any blob by ID.\\n2. **There is no public mainnet publisher.** Mainnet writes consume SUI + WAL on the publisher side \u2014 run your own, use an upload relay, or use the TypeScript SDK. Don\'t hunt for a free mainnet PUT endpoint; it doesn\'t exist by design.\\n3. **Blobs are public.** Never store secrets or personal data unencrypted.\\n4. **Blobs expire by epoch.** A stored blob lives for the epochs paid for \u2014 surface the `endEpoch` from the store response if the user needs durability.\\n\\n## Read a blob\\n\\n```bash\\n# by blob ID (the u256 ID, base64url \u2014 what walrus:// links carry)\\ncurl -s \\"https://aggregator.walrus-mainnet.walrus.space/v1/blobs/<BLOB_ID>\\"\\n\\n# by the Sui object ID of the Blob object\\ncurl -s \\"https://aggregator.walrus-mainnet.walrus.space/v1/blobs/by-object-id/<OBJECT_ID>\\"\\n```\\n\\n## Store a blob (testnet \u2014 free)\\n\\n```bash\\ncurl -s -X PUT \\"https://publisher.walrus-testnet.walrus.space/v1/blobs\\" -d \\"hello walrus\\"\\n# \u2192 {\\"newlyCreated\\":{\\"blobObject\\":{\\"blobId\\":\\"V7Zv\u2026\\",\\"size\\":28,\u2026}}}\\n# store for N epochs: \u2026/v1/blobs?epochs=5\\n# send the Blob object to a wallet: \u2026/v1/blobs?send_object_to=0x\u2026\\n```\\n\\nThen read it back from the testnet aggregator:\\n\\n```bash\\ncurl -s \\"https://aggregator.walrus-testnet.walrus.space/v1/blobs/V7Zv\u2026\\"\\n```\\n\\nVerified round-trip: `PUT` \u2192 `blobId V7ZvHXobPNriNB9f2PD8g_VWnAVIgKWAbPYxQZP9464` \u2192 `GET` returned the exact bytes.\\n\\n## Store on mainnet\\n\\nPick one:\\n\\n- **Run a publisher** \u2014 `walrus publisher` with a funded wallet ([operator guide](https://docs.wal.app/docs/operator-guide/aggregators/operating-aggregator)).\\n- **Upload relay / TypeScript SDK** \u2014 integrate `@mysten/walrus` directly; the SDK pays with your wallet\'s WAL + SUI.\\n\\n## Gotchas\\n\\n- If you store then immediately read a blob and get a 404 through a CDN-fronted aggregator, retry with backoff \u2014 the 404 may be cached from before propagation.\\n- A re-`PUT` of identical bytes returns `alreadyCertified` (same blob ID) instead of `newlyCreated` \u2014 idempotent, not an error.\\n- Most public endpoints cap requests at 10 MiB.\\n\\nLive docs: [docs.wal.app](https://docs.wal.app/docs/network-reference)."}]';
147126
+ const raw = '[{"name":"deepbook","description":"Read live market data from DeepBook, Sui\'s on-chain central limit order book \u2014 pools, tickers, order books, candles, trades \u2014 over a free public REST indexer. Use for Sui price checks, market depth, volume, or OHLCV questions. Read-only.","body":"# DeepBook: Market reads\\n\\n## Purpose\\n\\nDeepBook v3 is Sui\'s shared order book. Mysten runs a free public indexer \u2014 no key, no wallet:\\n\\n```text\\nhttps://deepbook-indexer.mainnet.mystenlabs.com\\n```\\n\\nPair names are `BASE_QUOTE` (e.g. `SUI_USDC`, `DEEP_USDC`, `WAL_USDC`). Get the live list from `/get_pools`.\\n\\n## Rules\\n\\n1. **Discover pairs first.** Pool names are exact \u2014 call `/get_pools` or `/ticker` before assuming a pair exists.\\n2. **Prices come pre-scaled.** Ticker/orderbook/candle prices are already in human units \u2014 don\'t re-divide by decimals.\\n3. **Check `isFrozen`.** A ticker entry with `isFrozen: 1` is an inactive pool \u2014 don\'t quote it as a live price.\\n4. **This is one venue.** DeepBook depth \u2260 all of Sui liquidity. For a best-execution swap across 20+ DEXs, use the `t2000-swap` skill; use DeepBook reads for order-book-grade data.\\n\\n## Endpoints\\n\\n```bash\\nB=https://deepbook-indexer.mainnet.mystenlabs.com\\n\\ncurl -s \\"$B/get_pools\\" # every pool + assets, decimals, tick/lot sizes\\ncurl -s \\"$B/ticker\\" # all pairs: last_price, 24h volume, isFrozen\\ncurl -s \\"$B/summary\\" # 24h stats per pair (bid/ask, high/low, % change)\\ncurl -s \\"$B/orderbook/SUI_USDC?level=2&depth=10\\" # live bids/asks (level 1 = top of book)\\ncurl -s \\"$B/ohclv/SUI_USDC?interval=1h&limit=24\\" # candles: [ts_ms, open, high, close, low, volume]\\ncurl -s \\"$B/trades/SUI_USDC?limit=5\\" # recent fills (price, size, side, tx digest)\\ncurl -s \\"$B/historical_volume/SUI_USDC?start_time=<unix_s>&end_time=<unix_s>\\"\\n```\\n\\nVerified live examples:\\n\\n```bash\\ncurl -s \\"$B/orderbook/SUI_USDC?level=2&depth=4\\"\\n# {\\"bids\\":[[\\"0.73174\\",\\"240\\"],\u2026],\\"asks\\":[[\\"0.732\\",\\"1392.2\\"],\u2026],\\"timestamp\\":\\"1783734413301\\"}\\n\\ncurl -s \\"$B/ticker\\" | python3 -c \\"import json,sys; print(json.load(sys.stdin)[\'SUI_USDC\'])\\"\\n# {\'last_price\': 0.732\u2026, \'base_volume\': \u2026, \'quote_volume\': \u2026, \'isFrozen\': 0}\\n```\\n\\n## Answer patterns\\n\\n- **\\"What\'s SUI trading at?\\"** \u2192 `/ticker`, read `SUI_USDC.last_price`, quote the venue (\\"on DeepBook\\").\\n- **\\"How deep is the book?\\"** \u2192 `/orderbook/<pair>?level=2&depth=20`, sum bid/ask sizes near mid.\\n- **\\"Chart the last day\\"** \u2192 `/ohclv/<pair>?interval=1h&limit=24`. Note the field order in the name: o-h-**c-l**-v.\\n- **\\"Is volume real?\\"** \u2192 `/trades/<pair>` rows carry the Sui tx `digest` \u2014 every fill is verifiable on-chain (`https://suiscan.xyz/mainnet/tx/<digest>`).\\n\\n## Gotchas\\n\\n- The candle endpoint is spelled `ohclv` (not `ohlcv`) \u2014 and the array order matches: `[ts, open, high, close, low, volume]`.\\n- Timestamps: candle/orderbook are **milliseconds**; `historical_volume` params are **seconds**.\\n- Trading (placing orders) needs a BalanceManager + the DeepBook SDK \u2014 out of scope here; this skill is reads.\\n\\nLive docs: [docs.sui.io \u2192 DeepBookV3 Indexer](https://docs.sui.io/onchain-finance/deepbookv3/deepbookv3-indexer)."},{"name":"sui-grpc","description":"Read Sui chain state over gRPC \u2014 balances, objects, transactions, coin metadata, names. Use for any direct Sui read; JSON-RPC deactivates July 31, 2026 (mainnet), so new integrations MUST use gRPC. Read-only.","body":"# Sui: Read the chain over gRPC\\n\\n## Purpose\\n\\nThe canonical way to read Sui in 2026. One client covers balances, objects, transactions, metadata, and name service.\\n\\n> **JSON-RPC is being retired (mainnet: July 31, 2026).** `SuiClient` / `suix_*` / `sui_*` HTTP methods stop working on public fullnodes. Everything below is the replacement surface, verified against mainnet.\\n\\n## Setup\\n\\n```js\\nimport { SuiGrpcClient } from \'@mysten/sui/grpc\';\\n\\nconst client = new SuiGrpcClient({\\n baseUrl: \'https://fullnode.mainnet.sui.io\',\\n network: \'mainnet\',\\n});\\n```\\n\\n## The reads\\n\\n```js\\n// One coin balance (owner + coinType)\\nconst { balance } = await client.core.getBalance({\\n owner: \'0x\u2026\',\\n coinType: \'0x2::sui::SUI\',\\n});\\n// balance.balance = total, split into coinBalance + addressBalance (SIP-58)\\n\\n// Every balance an address holds\\nconst { balances } = await client.core.listBalances({ owner: \'0x\u2026\' });\\n\\n// Coin metadata (decimals, symbol) \u2014 never hardcode decimals\\nconst { coinMetadata } = await client.core.getCoinMetadata({\\n coinType: \'0xdba3\u2026::usdc::USDC\',\\n});\\n\\n// Objects an address owns\\nconst { objects, hasNextPage, cursor } = await client.core.listOwnedObjects({\\n owner: \'0x\u2026\',\\n limit: 50,\\n});\\n// each: { objectId, version, digest, type, owner, content }\\n\\n// One object / one transaction\\nconst obj = await client.core.getObject({ objectId: \'0x\u2026\' });\\nconst tx = await client.core.getTransaction({ digest: \'\u2026\' });\\n\\n// SuiNS\\nconst { record } = await client.nameService.lookupName({ name: \'agent-id.sui\' });\\n```\\n\\n## Rules\\n\\n1. **Amounts are strings/bigints in base units.** Scale by `coinMetadata.decimals` for display; never `parseFloat` raw chain values into math you\'ll transact on.\\n2. **A balance has two pots (SIP-58).** `coinBalance` (coin objects) + `addressBalance` (address-balance accumulator) sum to `balance` \u2014 report the total unless debugging transfers.\\n3. **Paginate.** `listOwnedObjects` / `listCoins` return `cursor` + `hasNextPage`; loop until done for full inventories.\\n4. **Don\'t write from this skill.** Building + signing transactions is wallet territory \u2014 use the t2000 Agent Wallet (`t2 send \xB7 swap \xB7 pay`) or `@t2000/sdk`, which run on this same gRPC surface.\\n\\n## Field-masked reads (advanced)\\n\\nLarge objects/transactions support read masks to fetch only what you need:\\n\\n```js\\nconst tx = await client.ledgerService.getTransaction({\\n digest: \'\u2026\',\\n readMask: { paths: [\'effects\', \'events\'] },\\n});\\n```\\n\\n## Gotchas\\n\\n- The gRPC client returns **BigInt** for u64s \u2014 `JSON.stringify` throws on them; convert with a replacer: `(k, v) => typeof v === \'bigint\' ? v.toString() : v`.\\n- `getBalance` takes `owner`, not `address` \u2014 a wrong key name errors as `missing owner`.\\n- Public fullnode gRPC is rate-limited like RPC was; batch via list endpoints instead of hammering singles."},{"name":"sui-move-security","description":"Write and review Sui Move that touches value using OpenZeppelin\'s audited primitives instead of hand-rolled math or access control. Use when writing Move with fees, shares, swaps, or AMM math; when reviewing or auditing a Sui Move package; or when a contract needs ownership handoff, spending allowances, timelocks, or rate limiting. Teaches the never-roll-your-own rules and where each OZ package applies.","body":"# Sui Move Security \u2014 OpenZeppelin Contracts for Sui\\n\\n## Purpose\\n\\nIn May 2025 a single flawed overflow check in a shared math library \u2014 a\\n`checked_shl`-class function that silently passed a value it should have\\nrejected \u2014 led to the Cetus exploit: ~$223M drained from the largest DEX on\\nSui, and a corrupted fixed-point intermediate that multiple downstream\\nprotocols depended on. The lesson is structural, not incidental: **value-path\\nmath and privileged-capability handling must come from audited primitives,\\nnever be hand-rolled.**\\n\\n[OpenZeppelin Contracts for Sui](https://docs.openzeppelin.com/contracts-sui)\\n(MIT) is that library. This skill is the map; the SSOT is upstream \u2014 start\\nfrom the machine-readable entry point when you need detail:\\n<https://raw.githubusercontent.com/OpenZeppelin/contracts-sui/main/llms.txt>\\n\\n## Hard rules (apply to every Move review and every new module)\\n\\n1. **Never write `(a * b) / c` manually.** The intermediate product overflows\\n even when the final result would fit. Use `mul_div` (widens internally,\\n returns `Option`). Power-of-two denominator (Q64.64 / tick math)? Use\\n `mul_shr` \u2014 the Cetus exploit lived in exactly this operation class.\\n2. **Rounding is a protocol decision, not a detail.** Every OZ divide/shift/\\n root takes an explicit `RoundingMode` \u2014 there is no default. Rule of\\n thumb: round **down** on protocol-to-user payouts (vault shares both\\n directions \u2014 the vault keeps the remainder), **up** only for conservative\\n upper bounds the protocol absorbs, `nearest()` for quotes/display. If a\\n deposit rounds up or a withdrawal rounds up, you built a drain loop.\\n3. **Handle the `Option` at the boundary.** Overflow-prone ops return\\n `Option<T>`: abort with a domain error (`.destroy_or!(abort EMathOverflow)`),\\n cap at a safe value, or propagate \u2014 but never `destroy_some()` blind.\\n4. **Never shift with `<<` / `>>` on value paths.** Move\'s native shifts\\n silently discard bits. `checked_shl` / `checked_shr` return `None` when\\n any non-zero bit would be lost.\\n5. **`(a + b) / 2` overflows near type max** \u2014 use `average(a, b, mode)`.\\n6. **Decimal conversions go through `decimal_scaling`** (`safe_upcast_balance`\\n / `safe_downcast_balance`) \u2014 never a hand-written `* 10^k`. Downcasts\\n truncate; if the remainder matters, capture it before the downcast.\\n7. **`u64` is the standard width** (Sui coin balances, timestamps, gas).\\n Reach for `u128`/`u256` only when the domain demands it; never use `u512`\\n directly (it exists for the library\'s internal widening).\\n8. **Privileged capabilities need transfer policies.** Raw\\n `transfer::transfer(admin_cap, new_owner)` is a one-shot, typo-fatal\\n handoff. Use `openzeppelin_access` (two-step approvals, time-locked\\n transfers); for delayed privileged ops, `openzeppelin_timelock`.\\n\\n## Install (Move.toml \u2014 MVR, pin stable releases)\\n\\n```toml\\n[dependencies]\\nopenzeppelin_math = { r.mvr = \\"@openzeppelin-move/integer-math\\" }\\nopenzeppelin_fp_math = { r.mvr = \\"@openzeppelin-move/fixed-point-math\\" }\\nopenzeppelin_access = { r.mvr = \\"@openzeppelin-move/access\\" }\\nopenzeppelin_utils = { r.mvr = \\"@openzeppelin-move/utils\\" }\\n```\\n\\nVerify with `sui move build`. Each package ships compilable examples under\\nits `examples/` dir \u2014 read them before wiring (composition recipes, not docs\\nprose).\\n\\n## The package map (which one for which job)\\n\\n| Need | Package (MVR) | Teaching |\\n| --- | --- | --- |\\n| Fees, shares, swap quotes, interest | `@openzeppelin-move/integer-math` | `mul_div`/`mul_shr`/`average` + explicit rounding + `Option` boundary |\\n| Prices, ratios, signed deltas | `@openzeppelin-move/fixed-point-math` | 9-decimal `UD30x9`/`SD29x9` on `u128` \u2014 same explicit-rounding philosophy |\\n| Ownership handoff of caps | `@openzeppelin-move/access` | two-step approvals, time-locked transfers \u2014 no one-shot cap sends |\\n| Throttling on-chain actions | `@openzeppelin-move/utils` | rate limiter: token bucket, fixed window, cooldown |\\n| Bounded delegated spending | `openzeppelin_allowance` (path dep) | capability-keyed budgets \u2014 owner keeps custody |\\n| Scheduled/locked releases | `openzeppelin_finance` / `openzeppelin_timelock` (path deps) | vesting curves \xB7 delayed-operation controller |\\n\\n## Canonical snippet (fee quote, from the OZ docs)\\n\\n```move\\nmodule my_sui_app::pricing;\\n\\nuse openzeppelin_math::{rounding, u64};\\n\\nconst EMathOverflow: u64 = 0;\\n\\npublic fun quote_with_fee(amount: u64): u64 {\\n u64::mul_div(amount, 1025u64, 1000u64, rounding::nearest())\\n .destroy_or!(abort EMathOverflow)\\n}\\n```\\n\\n## Review checklist (auditing a Sui Move package)\\n\\n- [ ] Any manual `*` followed by `/` on a value path \u2192 replace with `mul_div`.\\n- [ ] Any `<<`/`>>` on amounts, prices, or liquidity \u2192 `checked_shl`/`checked_shr`.\\n- [ ] Every rounding direction stated and justified (who absorbs the remainder?).\\n- [ ] Every `Option`-returning call handled explicitly (no blind unwraps).\\n- [ ] Decimal conversions centralized through `decimal_scaling`.\\n- [ ] Admin/owner capabilities transferred via `openzeppelin_access` policies.\\n- [ ] Unbounded mint/spend/call paths \u2192 rate limiter or allowance vault.\\n- [ ] Deps pinned via MVR; `sui move build` + `sui move test` green.\\n\\n## Pointers (read on demand \u2014 never vendor these into your repo)\\n\\n- llms.txt (entry point): <https://raw.githubusercontent.com/OpenZeppelin/contracts-sui/main/llms.txt>\\n- Integer math guide (the rounding/overflow doctrine): <https://docs.openzeppelin.com/contracts-sui/1.x/math>\\n- Package catalogs: [contracts/](https://github.com/OpenZeppelin/contracts-sui/tree/main/contracts) \xB7 [math/](https://github.com/OpenZeppelin/contracts-sui/tree/main/math)\\n- Audits + scope: <https://github.com/OpenZeppelin/contracts-sui/tree/main/audits>\\n- OZ\'s own caveat: the library is audited but young (\\"experimental software\\") \u2014 using it is not a substitute for auditing YOUR package.\\n- General Move skills (object model, PTBs, testing): `npx skills add mystenlabs/skills --all`"},{"name":"suins","description":"Resolve SuiNS names (alice.sui) to Sui addresses and back, from an agent. Use when asked to look up a .sui name, find the address behind a name, or find the name for an address. Read-only \u2014 registering names happens at suins.io.","body":"# SuiNS: Resolve names\\n\\n## Purpose\\n\\nSuiNS is Sui\'s name service \u2014 `alice.sui` instead of `0x\u2026`. Two reads cover almost every task:\\n\\n- **Lookup** \u2014 name \u2192 target address (`agent-id.sui` \u2192 `0x6988\u20264532`)\\n- **Reverse lookup** \u2014 address \u2192 its default name\\n\\n## Rules\\n\\n1. **A null result is a valid answer.** A name can exist with no target address set \u2014 treat \\"no target\\" as \\"cannot pay this name\\", not an error.\\n2. **Never guess an address from a name.** If resolution returns nothing, stop and say so.\\n3. **Prefer gRPC.** Sui JSON-RPC is deactivated July 31, 2026 (mainnet) \u2014 do not build new resolution on `suix_resolveNameServiceAddress`.\\n4. **Sending to a name?** The t2000 wallet resolves SuiNS itself: `t2 send 5 USDC alice.sui` \u2014 no separate lookup step needed.\\n\\n## Resolve (gRPC \u2014 the current path)\\n\\n```js\\nimport { SuiGrpcClient } from \'@mysten/sui/grpc\';\\n\\nconst client = new SuiGrpcClient({\\n baseUrl: \'https://fullnode.mainnet.sui.io\',\\n network: \'mainnet\',\\n});\\n\\n// name \u2192 address\\nconst { record } = await client.nameService.lookupName({ name: \'agent-id.sui\' });\\nconsole.log(record.targetAddress); // 0x6988\u20264532\\nconsole.log(record.expirationTimestamp); // when the name expires\\n\\n// address \u2192 default name\\nconst rev = await client.nameService.reverseLookupName({ address: \'0x\u2026\' });\\nconsole.log(rev.record?.name);\\n```\\n\\nVerified against mainnet: `agent-id.sui` \u2192 `0x6988a92d5695909b7baa4d996324a873fbbeec94eec445eab99cc08ed30e4532`.\\n\\n## Resolve (JSON-RPC \u2014 works today, deactivated July 31, 2026 on mainnet)\\n\\n```bash\\ncurl -s -X POST https://fullnode.mainnet.sui.io \\\\\\n -H \\"content-type: application/json\\" \\\\\\n -d \'{\\"jsonrpc\\":\\"2.0\\",\\"id\\":1,\\"method\\":\\"suix_resolveNameServiceAddress\\",\\"params\\":[\\"agent-id.sui\\"]}\'\\n# \u2192 {\\"jsonrpc\\":\\"2.0\\",\\"id\\":1,\\"result\\":\\"0x6988\u20264532\\"}\\n```\\n\\nUse only as a stopgap in environments without a gRPC client. Migrate before the cutoff.\\n\\n## Registering and managing names\\n\\nRegistration, renewals, and subnames are transactions \u2014 use [suins.io](https://suins.io) (browser) or the [`@mysten/suins` SDK](https://docs.suins.io/developer/sdk) (programmatic). The t2000 stack mints its own namespaces this way: `@handle` \u2192 `<label>.agent-id.sui` via `t2 agent handle <label>`.\\n\\n## Gotchas\\n\\n- Names are lowercase; normalize before lookup.\\n- `expirationTimestamp` matters \u2014 an expired name stops resolving. Surface it when the user is about to rely on a name long-term.\\n- The name\'s **owner** (NFT holder) and **target address** are different fields \u2014 a name can point anywhere its owner sets."},{"name":"t2000-check-balance","description":"Check the t2000 Agent Wallet balance on Sui. Use when asked about wallet balance, how much USDC / USDsui / SUI is available, or total funds. Also use before any send, swap, or pay operation to confirm sufficient funds exist.","body":"# t2000: Check Balance\\n\\n## Purpose\\n\\nFetch the current wallet balance \u2014 stablecoin holdings (USDC, USDsui, other Sui-native stables) plus the SUI holding (used for swaps). Wallet only; **no savings or debt** rollup (the stack has no DeFi surface).\\n\\n## Commands\\n\\n```bash\\nt2 balance # human-readable summary\\nt2 balance --json # machine-parseable JSON (works on every command)\\nt2 balance --key <path> # use a non-default wallet key file\\n```\\n\\n## Output (default)\\n\\n```\\n USDC $150.00\\n USDsui $20.00\\n SUI $0.50 (0.5000 SUI \u2014 gas)\\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\\n Wallet total $170.50\\n```\\n\\nThe list shows every stablecoin with a balance \u2265 $0.01, sorted with USDC first. SUI shows separately as the gas reserve (its USD equivalent fluctuates with the market).\\n\\n## Output (--json)\\n\\n```json\\n{\\n \\"available\\": 170.0,\\n \\"stables\\": { \\"USDC\\": 150.0, \\"USDsui\\": 20.0 },\\n \\"sui\\": { \\"amount\\": 0.5, \\"usdValue\\": 0.5 },\\n \\"totalUsd\\": 170.5\\n}\\n```\\n\\n## Rules\\n\\n1. **Wallet-only.** This skill returns holdings, not savings or debt. If the user asks \\"what are my savings?\\" or \\"what\'s my health factor?\\", explain the wallet is payments-only \u2014 there is no savings/lending product in the stack.\\n2. **Always check before writes.** Run `t2 balance` (or call `t2000_balance` via MCP) before any `t2 send`, `t2 swap`, or `t2 pay` so the user sees what\'s actually spendable.\\n3. **--json is universal.** Every t2 command supports `--json` \u2014 surface this when scripting.\\n\\n## Notes\\n\\n- `sui.usdValue` is an estimate at current SUI price; it fluctuates.\\n- If balance shows $0.00 and the wallet was just created, fund it first via `t2 fund` (prints the address + QR).\\n- USDC + USDsui sends are gasless (Sui foundation sponsored), so you can send with 0 SUI held. Swaps via Cetus DO need a small SUI balance."},{"name":"t2000-code-delegate","description":"Delegate well-specified coding grunt work to t2 code, the private coding agent on the t2000 rail, instead of burning frontier tokens on it. Use when a task is mechanical and verifiable \u2014 sweeps, renames, test-fix loops, applying a written plan, doc updates across many files \u2014 and you (the host agent) can review the diff afterwards. Runs `t2code exec` headlessly in the terminal; open-model pricing, private by default.","body":"# t2000: Delegate Coding Work to t2 code\\n\\n## Purpose\\n\\nYou are an expensive frontier agent. Most coding work does not need you: once a\\ntask is well-specified, the multi-file editing loop is mechanical. Hand that\\nloop to **t2 code** \u2014 it runs the whole thing on open models via the t2000\\nrouter (private by default, never a closed lab), while you stay on\\norchestration and review. That split is what moves the bill.\\n\\nYour job when delegating: **specify, dispatch, supervise, review, report.**\\n\\n## When to delegate (and when not)\\n\\nDelegate when ALL of these hold:\\n- The task is **well-specified**: you can state the goal, the scope (which\\n files/areas), and a verification step (tests pass, grep comes back empty,\\n build is green).\\n- It is **mechanical at execution time**: sweeps, renames, applying an\\n agreed-on plan, fixing tests to green, dependency bumps with known fallout,\\n repetitive doc/comment updates. This includes executing a self-contained\\n plan file written by a planning skill (e.g. shadcn/improve\'s `plans/*.md` \u2014\\n point the spec at the plan file and its verification gates).\\n- You can **verify the result from the diff + the verification step** without\\n re-deriving every decision.\\n\\nDo NOT delegate:\\n- Ambiguous or architectural work (multiple valid interpretations, API design,\\n trade-off calls) \u2014 that is your job.\\n- Anything where a wrong-but-plausible edit would be hard to catch in review.\\n- Tasks the user asked YOU to do interactively.\\n\\n## How to dispatch\\n\\nRun t2 code headlessly in the terminal, in the same working tree:\\n\\n```bash\\nt2code exec \\"<task spec>\\"\\n```\\n\\n- The final answer streams to stdout; progress (tool calls, subagents) goes to\\n stderr. Add `--json` if you want the raw NDJSON event stream to supervise\\n programmatically.\\n- Exit code 0 = clean finish, 1 = error.\\n- **Auth is not your problem**: t2code reads the user\'s persisted console key\\n (or `T2000_API_KEY`) itself. If it prints \\"Not logged in\\", tell the user to\\n run `t2code login` once.\\n- **Privacy is not your problem either**: t2 code applies the repo\'s pinned\\n privacy mode (`.t2000/config.json`) or the user\'s global choice. Do not\\n override it.\\n\\n### Writing the task spec\\n\\nThe spec is the whole game. Include, in one prompt string:\\n1. **Goal** \u2014 what done looks like, one sentence.\\n2. **Scope** \u2014 directories/files in bounds, anything out of bounds.\\n3. **Constraints** \u2014 conventions to follow, things not to touch.\\n4. **Verification** \u2014 the exact command(s) that must pass (`bun test`,\\n `pnpm typecheck`, a grep that must return nothing).\\n\\nExample:\\n\\n```bash\\nt2code exec \\"Rename getCwd to getCurrentWorkingDirectory across src/ and\\nupdate all call sites. Do not touch vendored code under src/vendor/. When\\ndone, run \'pnpm typecheck\' and fix any errors it reports. Verification:\\n\'rg -n \\\\\\"getCwd\\\\\\\\b\\\\\\" src/\' must return no matches and typecheck must pass.\\"\\n```\\n\\n## Supervising the run\\n\\n- Watch stderr for progress. If the run goes quiet for a long time or loops on\\n the same failing action, kill it and re-dispatch with a tighter spec.\\n- For risky or parallel work, dispatch in a separate git worktree and merge\\n after review instead of running in the main tree.\\n\\n## Reviewing and reporting\\n\\nAfter the run exits:\\n1. Run `git diff` (or use your host\'s diff UI) and actually read it.\\n2. Run the verification step yourself \u2014 do not trust \\"done\\" claims.\\n3. If the diff is wrong in a bounded way, fix it yourself or re-dispatch with\\n the correction named explicitly.\\n4. Report back to the user: what was delegated, what changed, verification\\n result, anything you corrected.\\n\\nYou own the result. Delegation changes who types, not who is accountable."},{"name":"t2000-job","description":"Escrow USDC for agent-to-agent deliverable work (A2A jobs). Use when hiring another agent for async work (research reports, builds, SLA tasks) or when selling deliverable work yourself (list a service: fixed price + SLA, no server needed) \u2014 anything where funds must commit before delivery starts and delivery takes minutes to days. Funds lock in a shared Sui Move object (no platform custody); release/refund are pure functions of state, clock, and caller. For instant request/response API calls use t2000-pay instead \u2014 x402 settle-then-serve needs no escrow.","body":"# t2000: A2A Escrow Jobs\\n\\n## Status\\nActive \u2014 bundled with `@t2000/cli` (no separate install).\\n\\n**No platform custody.** Each job is one shared Move object\\n(`a2a_escrow::escrow::Job<USDC>`) on Sui mainnet holding the funds itself \u2014\\nno treasury, no admin key, t2000 never touches the money. Job transactions\\nare sponsored (gas co-paid by the rail), so the wallet needs USDC only.\\n\\n## When to use which\\n\\n| Situation | Tool |\\n|---|---|\\n| Instant request/response paid API call | `t2 pay` (x402 settle-then-serve \u2014 no charge on failure by construction) |\\n| Async deliverable work: funds must commit BEFORE work starts, delivery takes minutes\u2013days | `t2 job` (this skill) |\\n\\n## The lifecycle\\n\\n```\\nFUNDED \u2500\u2500deliver (seller, before deadline)\u2500\u2500\u25B6 DELIVERED\\nFUNDED \u2500\u2500refund (ANYONE, after deadline)\u2500\u2500\u25B6 REFUNDED \u2192 buyer\\nDELIVERED \u2500\u2500release (buyer accepts)\u2500\u2500\u25B6 RELEASED \u2192 seller\\nDELIVERED \u2500\u2500release (ANYONE, review window lapsed)\u2500\u2500\u25B6 RELEASED\\nDELIVERED \u2500\u2500reject (buyer, within window)\u2500\u2500\u25B6 REJECTED \u2192 split per terms\\n```\\n\\nThe two timeout paths are permissionless cranks: a ghosting buyer can\'t strand\\na delivering seller, and a no-show seller can never keep committed funds.\\nJobs are capped at **50 USDC**.\\n\\n**Protocol fee: 5%**, enforced by the contract on the seller-bound payout at\\nsettlement (release, or the seller\'s share of a reject split). The bps lock\\ninto the job at create \u2014 later fee changes never touch a funded job. Refunds\\nto the buyer are always fee-free.\\n\\n## Buyer flow \u2014 services (the easy path)\\n\\nSellers list **services** \u2014 fixed price, delivery SLA, what to provide, what\\nyou get. Buy one and every term comes from the listing:\\n\\n```bash\\n# Find work to buy (free-text search across every agent)\\nt2 browse \\"market report\\"\\n\\n# Fund the escrow at the listed price/SLA/terms. --requirements is what the\\n# seller asked for (JSON or text); it\'s stored content-addressed and its\\n# sha256 is pinned on-chain as the job\'s spec hash (tamper-evident).\\nt2 job create --agent 0xSELLER --service sui-market-report \\\\\\n --requirements \'{\\"token\\":\\"DEEP\\"}\'\\n```\\n\\n## Buyer flow \u2014 direct (explicit terms)\\n\\n```bash\\n# 1. Escrow the funds + terms in ONE transaction. The spec (file or text) is\\n# hashed on-chain so neither side can rewrite the brief later.\\nt2 job create 5 0xSELLER --spec brief.md --deadline 24h --review 24h\\n\\n# 2. Hand the printed job id to the seller (their listing\'s contact/endpoint).\\n\\n# 3. Watch it \u2014 prints state + what YOU can do right now, exits when settled.\\nt2 job watch 0xJOB\\n\\n# 4a. Delivery arrived and it\'s good \u2192 pay the seller.\\nt2 job release 0xJOB\\n# Then (optional, recommended) rate the work \u2014 receipt-bound to the job,\\n# shows on the seller\'s agents.t2000.ai profile. Re-run to edit.\\nt2 job review 0xJOB --stars 5 --text \\"Fast, exactly as specced.\\"\\n\\n# 4b. Delivery arrived and it\'s bad \u2192 reject within your review window.\\n# Funds split per the ratio agreed at create (default 80% you / 20% seller).\\nt2 job reject 0xJOB\\n\\n# 4c. No delivery by the deadline \u2192 reclaim everything.\\nt2 job refund 0xJOB\\n```\\n\\n`--split <bps>` at create sets YOUR share on reject (default 8000 = 80%).\\nDo nothing after a delivery and the review window lapses \u2192 anyone can release\\nto the seller, so review deliveries promptly.\\n\\n## Seller flow (doing the work)\\n\\nTo get hired without running any server, list a service first (once):\\n\\n```bash\\nt2 service create --name \\"Sui market report\\" --price 5 --sla 24h \\\\\\n --description \\"Research report on any Sui token\\" \\\\\\n --deliverable \\"PDF report, 2+ pages, sources cited\\" \\\\\\n --requirements \'{\\"token\\":\\"string \u2014 symbol or coin type\\"}\'\\n# manage with: t2 service list \xB7 t2 service retire <slug>\\n```\\n\\nHear about hires the moment the escrow funds (no server, no webhook):\\n\\n```bash\\n# The provider inbox \u2014 every job where YOU are the seller. Announces new\\n# jobs + state changes live and prints your next verb at each step.\\nt2 job watch --mine # --once for a snapshot; --json for machines\\n```\\n\\nThen for each job:\\n\\n```bash\\n# 1. NEVER start work on a bare job id. Verify it on-chain first:\\n# funded, pays YOUR wallet, covers your price, deadline is workable.\\nt2 job verify 0xJOB --price 5\\n# exit code 0 = safe to start; 1 = do NOT start (reasons printed)\\n\\n# 1b. Service job? Read the buyer\'s requirements (content is verified\\n# against the on-chain spec hash before it prints):\\nt2 job spec 0xJOB\\n\\n# 2. Do the work. Post your proof-of-delivery BEFORE the deadline \u2014\\n# a file (hashed sha256) or a 0x\u2026 hash of the artifact:\\nt2 job deliver 0xJOB report.pdf\\n\\n# 3. Buyer accepts \u2192 funds land in your wallet. Buyer ghosts \u2192 once their\\n# review window lapses, run release yourself (permissionless):\\nt2 job release 0xJOB\\n```\\n\\n## Command reference\\n\\n| Command | Who | What |\\n|---|---|---|\\n| `t2 browse [query]` | buyer | Search agent services across every agent |\\n| `t2 job create <usdc> <seller> --spec <s> [--deadline 24h] [--review 24h] [--split 8000]` | buyer | Create + fund in one PTB (direct terms) |\\n| `t2 job create --agent <addr> --service <slug> [--requirements <r>]` | buyer | Buy a service \u2014 terms come from the listing |\\n| `t2 service create/list/retire` | seller | Manage your services (signed, gasless, no server) |\\n| `t2 job verify <jobId> --price <usdc>` | seller | On-chain escrow check before starting work |\\n| `t2 job spec <jobId>` | seller | Read the buyer\'s requirements (hash-verified) |\\n| `t2 job deliver <jobId> <file-or-hash>` | seller | Post delivery commitment before the deadline |\\n| `t2 job watch <jobId> [--interval 15] [--once]` | either | Poll state + your available actions |\\n| `t2 job watch --mine [--once]` | seller | The provider inbox \u2014 all jobs selling to you, live |\\n| `t2 job release <jobId>` | buyer / anyone after window | Funds \u2192 seller |\\n| `t2 job reject <jobId>` | buyer, within window | Split per create terms |\\n| `t2 job refund <jobId>` | anyone, after deadline | Funds \u2192 buyer |\\n| `t2 job review <jobId> --stars <1-5> [--text \\"\u2026\\"]` | buyer, after release | Rate the work \u2014 one review per released job, re-run to edit |\\n\\nAll commands take `--json` for machine output; `watch --json` prints one\\nsnapshot (`{ job, yourActions, terminal }`) and exits.\\n\\n## Safety\\n- Verify before work: `t2 job verify` \u2014 state, payee, amount, runway.\\n- The spec hash pins the brief; keep the original file to prove terms.\\n- Deadlines and the review window are on-chain clocks (`0x6`), not promises.\\n- Reject split is fixed at create \u2014 nobody can move the goalposts later.\\n- v1 job cap: 50 USDC. Larger engagements: split into milestone jobs.\\n\\n## Errors\\n- `INSUFFICIENT_BALANCE`: not enough USDC to fund the escrow\\n- `INVALID_AMOUNT`: over the 50 USDC v1 cap, past deadline, or bad split bps\\n- Move aborts surface with the failing rule (e.g. rejecting after the review\\n window closed, delivering past the deadline)"},{"name":"t2000-mcp","description":"Connect a t2000 Agent Wallet to Claude Desktop, Cursor, Cline, Continue, or any MCP-compatible client. Use when asked to set up MCP, paste an MCP server config, install @t2000/mcp, or troubleshoot why the MCP server \\"doesn\'t do anything\\" when run from a terminal. v4 surface: 14 tools (6 read + 4 write + 3 Private Inference + 1 limit-view) and one skill-* prompt per SKILL.md in t2000-skills/skills/.","body":"# t2000: MCP Server\\n\\n## Purpose\\n\\nExpose a t2000 Agent Wallet to any MCP-compatible AI client over stdio. **14 tools + N skill prompts** (one per `SKILL.md` in `t2000-skills/skills/`). No global install required \u2014 the recommended path uses `npx` so the AI client always pulls the latest published version.\\n\\n## \u26A0\uFE0F The most common confusion\\n\\n**`npx @t2000/mcp` is NOT a command you run from a terminal to \\"use\\" the MCP server.** It is a JSON-RPC server that listens silently on `stdin`. If you run it manually it will appear to hang \u2014 that\'s correct behavior. It is meant to be launched as a subprocess by an AI client (Claude Desktop, Cursor, etc.) which speaks JSON-RPC to it over `stdin`/`stdout`.\\n\\nThe JSON snippets below go into your **AI client\'s MCP settings file**, not into a shell.\\n\\n## Setup\\n\\n### 1. Create a wallet (one-time, in a terminal)\\n\\n```bash\\n# Install CLI long enough to bootstrap a wallet\\nnpm install -g @t2000/cli\\nt2 init\\n```\\n\\nThat\'s it. No PIN. No safeguards gate. The MCP server starts as soon as the wallet file exists at `~/.t2000/wallet.key`.\\n\\n> Spending limits are ON by default ($25/tx, $100/day cumulative; adjust with `t2 limit set --per-tx 50` / `--daily 200`, clear with `t2 limit reset`). Every write \u2014 CLI **and** MCP \u2014 honors the caps and throws `LIMIT_EXCEEDED` when exceeded (enforced in `@t2000/sdk`). The MCP `t2000_limit` tool surfaces the caps for the LLM to read; it cannot raise or clear them.\\n\\n### 2. Wire MCP into your AI client \u2014 the easy way\\n\\n```bash\\nt2 mcp install\\n```\\n\\nNot interactive \u2014 it detects installed clients (Claude Desktop, Cursor, Windsurf) and writes the correct config block into each one it finds, reporting \\"configured\\" or \\"already configured\\" per client. Idempotent \u2014 safe to re-run. Then restart the client. For clients it doesn\'t auto-detect (Cline, Continue, Codex, \u2026), use the manual JSON below.\\n\\n### 2-alt. Manual MCP config\\n\\nRecommended (auto-updates on every launch, no global install):\\n\\n```json\\n{\\n \\"mcpServers\\": {\\n \\"t2000\\": {\\n \\"command\\": \\"npx\\",\\n \\"args\\": [\\"-y\\", \\"@t2000/mcp@latest\\"]\\n }\\n }\\n}\\n```\\n\\nAlternative (if `@t2000/cli` is already installed globally):\\n\\n```json\\n{\\n \\"mcpServers\\": {\\n \\"t2000\\": {\\n \\"command\\": \\"t2000\\",\\n \\"args\\": [\\"mcp\\", \\"start\\"]\\n }\\n }\\n}\\n```\\n\\n> The install ships two equivalent bins: **`t2`** (canonical) and **`t2000`** (alias). Either works as the `command` in the config block.\\n\\n### 3. Restart the client\\n\\nThe client spawns the MCP server as a subprocess on startup. You should see `t2000_*` tools appear in the tool list.\\n\\n## Per-client config file paths\\n\\n| Client | Config file |\\n|--------|-------------|\\n| Claude Desktop (macOS) | `~/Library/Application Support/Claude/claude_desktop_config.json` |\\n| Claude Desktop (Windows) | `%APPDATA%\\\\Claude\\\\claude_desktop_config.json` |\\n| Cursor | Settings \u2192 MCP \u2192 Add new MCP server (or `~/.cursor/mcp.json`) |\\n| Cline | VSCode settings \u2192 `cline.mcpServers` |\\n| Continue | `~/.continue/config.json` under `mcpServers` |\\n\\n`t2 mcp install` writes the correct block into each of these automatically.\\n\\n## Verification (optional, before wiring into a client)\\n\\nConfirm the server responds to a real MCP `initialize` request:\\n\\n```bash\\nprintf \'%s\\\\n\' \\\\\\n \'{\\"jsonrpc\\":\\"2.0\\",\\"id\\":1,\\"method\\":\\"initialize\\",\\"params\\":{\\"protocolVersion\\":\\"2024-11-05\\",\\"capabilities\\":{},\\"clientInfo\\":{\\"name\\":\\"test\\",\\"version\\":\\"1.0\\"}}}\' \\\\\\n | npx -y @t2000/mcp@latest\\n```\\n\\nYou should see a JSON response containing `\\"serverInfo\\":{\\"name\\":\\"t2000\\"\u2026}` and exit. If you see that, the server is healthy and ready to be launched by a client.\\n\\n## Available Tools (14)\\n\\n### Read (6)\\n\\n| Tool | Description |\\n|------|-------------|\\n| `t2000_balance` | Current wallet balance (USDC + USDsui + SUI + gas reserve). |\\n| `t2000_address` | Wallet address. |\\n| `t2000_receive` | Generate a payment request: address + Payment Kit URI + nonce. |\\n| `t2000_history` | Recent on-chain activity (sends / swaps / pays). |\\n| `t2000_services` | Discover x402 services (gateway catalog at mpp.t2000.ai). |\\n| `t2000_agents` | Look up agents in the directory (agents.t2000.ai) \u2014 registered on-chain Agent IDs. |\\n\\n### Write (4)\\n\\nAll support `dryRun: true` for previews without signing (where applicable).\\n\\n| Tool | Description |\\n|------|-------------|\\n| `t2000_send` | Send USDC / USDsui / SUI. Asset REQUIRED. USDC + USDsui are gasless. |\\n| `t2000_swap` | Swap tokens via Cetus Aggregator. Requires SUI for gas. |\\n| `t2000_pay` | Pay for an x402-protected API service (USDC, gasless). |\\n| `t2000_agent_sell` | List (or remove) this agent\'s x402 endpoint on its public Agent ID profile \u2014 live-probed first, then one sponsored gasless signature. `catalog: true` also lists it in the MPP catalog (machine-gated, per-gate results). Does NOT spend funds. |\\n### Private Inference (3)\\n\\nNeed a `T2000_API_KEY` in the client\'s env config.\\n\\n| Tool | Description |\\n|------|-------------|\\n| `t2000_chat` | Private (zero-retention) or confidential (GPU-TEE) inference. |\\n| `t2000_models` | The Private Inference model catalog. |\\n| `t2000_verify` | Trustlessly verify a confidential receipt (`rcpt-\u2026`). |\\n\\n### Settings (1)\\n\\n| Tool | Description |\\n|------|-------------|\\n| `t2000_limit` | View the user\'s spending caps (on by default: $25/tx \xB7 $100/day) from `~/.t2000/config.json`. READ-ONLY \u2014 the LLM cannot set or clear limits via MCP. |\\n\\n> **v3 \u2192 v4 deletions.** The pre-v4 surface was 27 tools (DeFi save/withdraw/borrow/repay/claim, positions/rates/health/earnings/fund_status, contacts/contact_add/contact_remove, config/lock, overview, deposit_info). All deleted as part of `SPEC_AGENT_WALLET_GREENFIELD` \u2014 see the `t2000-setup` skill for the v4 product story. DeFi was removed from the stack entirely (2026-06-14); local contacts are deprecated in favor of SuiNS (`alice.sui`).\\n\\n## Prompts\\n\\nThe MCP server auto-registers one `skill-<short-name>` prompt for every `SKILL.md` baked into the bundle. The `t2000-` prefix is stripped; other prefixes (like `mpp-`) are preserved for disambiguation.\\n\\nThe current set of skill prompts mirrors `t2000-skills/skills/`:\\n\\n| Prompt | Maps to |\\n|--------|---------|\\n| `skill-setup` | `t2000-setup` \u2014 one-prompt install entry point |\\n| `skill-check-balance` | `t2000-check-balance` |\\n| `skill-send` | `t2000-send` |\\n| `skill-receive` | `t2000-receive` |\\n| `skill-swap` | `t2000-swap` |\\n| `skill-pay` | `t2000-pay` |\\n| `skill-services` | `t2000-services` |\\n| `skill-mcp` | `t2000-mcp` (this skill) |\\n| `skill-verify` | `t2000-verify` |\\n\\nInvoking the prompt loads the full skill markdown as the user message \u2014 equivalent to the agent reading the skill from `t2000.ai/skills/<slug>`. Skill files are baked into the `@t2000/mcp` bundle at build time, so they\'re always in sync with the published version.\\n\\n> The v3 \\"workflow prompts\\" (`financial-report`, `optimize-yield`, `sweep`, `risk-check`, etc., 14 total) were deleted in v4 Phase B \u2014 they composed against the dead DeFi skill set. Multi-step coordination is now an LLM concern (the v4 surface is small enough \u2014 14 tools \u2014 that pre-baked workflows add no value).\\n\\n## Troubleshooting\\n\\n| Symptom | Cause | Fix |\\n|---------|-------|-----|\\n| `npx @t2000/mcp` \\"hangs\\" with no output | Working as designed \u2014 server is waiting for JSON-RPC on stdin | Don\'t run it manually; let the AI client launch it |\\n| Server fails with `WALLET_NOT_FOUND` | No wallet at `~/.t2000/wallet.key` | Run `t2 init` first |\\n| Server fails with `WALLET_CORRUPT` | File at `~/.t2000/wallet.key` is not a v4 wallet (e.g. a pre-v4 file, hand-edited JSON, or a wallet from a different tool) | Move or delete the file, then run `t2 init` to create a fresh wallet |\\n| Client shows no `t2000_*` tools after restart | Wrong config path, or stale npx cache | Verify with the `printf | npx ...` test above; clear cache with `rm -rf ~/.npm/_npx` |\\n| `SuiClient export not found` error from old install | Cached pre-fix bundle in `~/.npm/_npx` | `rm -rf ~/.npm/_npx` then restart the client |\\n\\n## Security\\n\\n- v4 wallets are plain Bech32 JSON files (`0o600` perms) \u2014 no PIN. Anyone with read access to `~/.t2000/wallet.key` owns the wallet.\\n- Local-only stdio transport \u2014 the key never leaves the machine.\\n- `dryRun: true` previews operations before signing (on `t2000_send`).\\n- Spending limits (default $25/tx \xB7 $100/day; `t2 limit set`) gate ALL writes \u2014 CLI and MCP \u2014 enforced in `@t2000/sdk`; `t2000_limit` is read-only."},{"name":"t2000-pay","description":"Pay for an x402-protected API service using the t2000 wallet. Use when asked to call an AI model, search the web, generate images, send email, buy gift cards, send physical mail, check weather, execute code, or any task that requires a paid API. Handles the full x402 402 challenge automatically. Use t2000_services to discover all available services first.","body":"# t2000: Pay for x402 API Service\\n\\n## Status\\nActive \u2014 bundled with `@t2000/cli` (no separate install).\\n\\n**USDC payment is gasless.** The 402 challenge response is a `0x2::balance::send_funds` Move call, which is in Sui\'s foundation-sponsored allowlist. The wallet can pay even with 0 SUI in the gas reserve.\\n\\n## Purpose\\nMake a paid HTTP request to any x402-protected endpoint. Handles the 402\\nchallenge, pays via Sui USDC, and returns the API response.\\n\\n## Service Discovery\\nBefore calling `t2 pay`, discover available services:\\n```bash\\n# CLI \u2014 search by name / category / endpoint\\nt2 services search \\"image\\" # find image-gen services\\nt2 services search \\"chat\\" # find chat/completion endpoints\\nt2 services search \\"\\" # list everything\\n\\n# CLI \u2014 inspect a service or endpoint\\nt2 services inspect https://mpp.t2000.ai/openai\\nt2 services inspect https://mpp.t2000.ai/openai/v1/chat/completions\\n\\n# MCP \u2014 full catalog JSON\\nt2000_services\\n```\\n\\nMost services are hosted at `https://mpp.t2000.ai/`; the catalog also federates **direct sellers** (marked `direct` \u2014 e.g. JMPR Travel at `agent.jmpr.world`) whose endpoints live on their own origin and settle straight to their wallet. `t2 pay` works identically for both; note the gateway\'s no-charge-on-failure guarantee covers proxied services only. See the `t2000-services` skill for the full discovery workflow.\\n\\n## Command\\n```bash\\nt2 pay <url> [options]\\n```\\n\\n## Options\\n| Option | Description | Default |\\n|--------|-------------|---------|\\n| `--method <method>` | HTTP method (GET, POST, PUT) | GET (auto-promotes to POST when `--data` is set) |\\n| `--data <json>` | Request body for POST/PUT (JSON bodies default `content-type: application/json`) | \u2014 |\\n| `--max-price <amount>` | Max USDC to auto-approve (enforced before any payment) | $1.00 |\\n| `--header <key=value>` | Additional HTTP header (repeatable) | \u2014 |\\n| `--estimate` | Show the price without paying (no funds spent) | \u2014 |\\n| `--force` | Override spending limits for this call (see `t2 limit`) | \u2014 |\\n\\n## Available Services\\n\\n> **The live catalog is the only source of truth for what\'s available and what it costs.**\\n> Discover services and current per-endpoint prices with `t2000_services` (MCP) or\\n> `GET https://mpp.t2000.ai/api/services`. Inspect one with `t2 services inspect <url>`.\\n> Prices are NOT listed here on purpose \u2014 they would drift from the catalog. Resolve the\\n> real price at call time (the `--max-price` ceiling guards against overpaying), or run\\n> `t2 pay <url> --estimate` to see what would be charged before paying.\\n\\nThe catalog spans every major AI + data API, grouped roughly as:\\n\\n- **AI models & reasoning** \u2014 OpenAI, Anthropic (Claude), Google Gemini, DeepSeek, Groq, Together AI, Perplexity, Mistral, Cohere (chat, embeddings, rerank).\\n- **Media & generation** \u2014 OpenAI (images, text-to-speech), fal.ai (Flux, Recraft, Whisper, Stable Audio), Together AI (images), ElevenLabs (TTS, sound effects), Replicate, Stability AI, AssemblyAI.\\n- **Search** \u2014 Brave, Exa, Serper, SerpAPI, NewsAPI.\\n- **Web & documents** \u2014 Firecrawl (scrape / crawl / map / extract), Jina Reader, ScreenshotOne, PDFShift, QR Code.\\n- **Data & finance** \u2014 OpenWeather, Google Maps (geocode / places / directions), CoinGecko, Alpha Vantage, ExchangeRate.\\n- **Translation** \u2014 DeepL, Google Translate.\\n- **Intelligence & security** \u2014 Hunter.io, IPinfo, VirusTotal.\\n- **Tools & utility** \u2014 Judge0 (code exec), Resend (email), Pushover (push), Short.io (URL shortener), TinyPNG (image compression & resize).\\n- **Commerce** \u2014 Lob (postcards, letters, address verification).\\n\\nThis list is a capability map, not the exhaustive endpoint set \u2014 always discover via the catalog before calling.\\n\\n## Example Commands\\n\\n### Ask an AI model\\n```bash\\nt2 pay https://mpp.t2000.ai/openai/v1/chat/completions \\\\\\n --data \'{\\"model\\":\\"gpt-4o\\",\\"messages\\":[{\\"role\\":\\"user\\",\\"content\\":\\"Explain quantum computing in 3 sentences\\"}]}\'\\n```\\n\\n### Search the web\\n```bash\\nt2 pay https://mpp.t2000.ai/brave/v1/web/search \\\\\\n --data \'{\\"q\\":\\"latest Sui blockchain news\\"}\'\\n```\\n\\n### Generate an image\\n```bash\\nt2 pay https://mpp.t2000.ai/fal/fal-ai/flux/dev \\\\\\n --data \'{\\"prompt\\":\\"a futuristic city at sunset, cyberpunk style\\"}\'\\n```\\n\\n### Check weather\\n```bash\\nt2 pay https://mpp.t2000.ai/openweather/v1/weather \\\\\\n --data \'{\\"q\\":\\"Tokyo\\"}\'\\n```\\n\\n### Send an email\\n```bash\\nt2 pay https://mpp.t2000.ai/resend/v1/emails \\\\\\n --data \'{\\"from\\":\\"agent@t2000.ai\\",\\"to\\":\\"user@example.com\\",\\"subject\\":\\"Hello\\",\\"text\\":\\"Sent by an AI agent\\"}\'\\n```\\n\\n### Execute code\\n```bash\\nt2 pay https://mpp.t2000.ai/judge0/v1/submissions \\\\\\n --data \'{\\"source_code\\":\\"print(42)\\",\\"language_id\\":71}\'\\n```\\n\\n### Send physical mail\\n```bash\\n# Send a postcard\\nt2 pay https://mpp.t2000.ai/lob/v1/postcards \\\\\\n --max-price 2 \\\\\\n --data \'{\\n \\"to\\":{\\"name\\":\\"Jane Doe\\",\\"address_line1\\":\\"123 Main St\\",\\"address_city\\":\\"San Francisco\\",\\"address_state\\":\\"CA\\",\\"address_zip\\":\\"94105\\"},\\n \\"from\\":{\\"name\\":\\"AI Agent\\",\\"address_line1\\":\\"456 Oak Ave\\",\\"address_city\\":\\"Palo Alto\\",\\"address_state\\":\\"CA\\",\\"address_zip\\":\\"94301\\"},\\n \\"front\\":\\"https://example.com/front.png\\",\\n \\"back\\":\\"https://example.com/back.png\\",\\n \\"use_type\\":\\"operational\\"\\n }\'\\n\\n# Send a letter\\nt2 pay https://mpp.t2000.ai/lob/v1/letters \\\\\\n --max-price 2 \\\\\\n --data \'{\\n \\"to\\":{\\"name\\":\\"Jane Doe\\",\\"address_line1\\":\\"123 Main St\\",\\"address_city\\":\\"San Francisco\\",\\"address_state\\":\\"CA\\",\\"address_zip\\":\\"94105\\"},\\n \\"from\\":{\\"name\\":\\"AI Agent\\",\\"address_line1\\":\\"456 Oak Ave\\",\\"address_city\\":\\"Palo Alto\\",\\"address_state\\":\\"CA\\",\\"address_zip\\":\\"94301\\"},\\n \\"file\\":\\"https://example.com/letter.pdf\\",\\n \\"use_type\\":\\"operational\\",\\n \\"color\\":false\\n }\'\\n\\n# Verify a US address\\nt2 pay https://mpp.t2000.ai/lob/v1/verify \\\\\\n --data \'{\\"primary_line\\":\\"123 Main St\\",\\"city\\":\\"San Francisco\\",\\"state\\":\\"CA\\",\\"zip_code\\":\\"94105\\"}\'\\n```\\n\\n### Get directions\\n```bash\\nt2 pay https://mpp.t2000.ai/googlemaps/v1/directions \\\\\\n --data \'{\\"origin\\":\\"San Francisco, CA\\",\\"destination\\":\\"Palo Alto, CA\\"}\'\\n```\\n\\n### Get crypto prices\\n```bash\\nt2 pay https://mpp.t2000.ai/coingecko/v1/price \\\\\\n --data \'{\\"ids\\":\\"sui,bitcoin,ethereum\\",\\"vs_currencies\\":\\"usd\\"}\'\\n```\\n\\n### Get a stock quote\\n```bash\\nt2 pay https://mpp.t2000.ai/alphavantage/v1/quote \\\\\\n --data \'{\\"symbol\\":\\"AAPL\\"}\'\\n```\\n\\n### Get breaking news\\n```bash\\nt2 pay https://mpp.t2000.ai/newsapi/v1/headlines \\\\\\n --data \'{\\"country\\":\\"us\\",\\"category\\":\\"technology\\"}\'\\n```\\n\\n### Translate text\\n```bash\\nt2 pay https://mpp.t2000.ai/deepl/v1/translate \\\\\\n --data \'{\\"text\\":[\\"Hello, how are you?\\"],\\"target_lang\\":\\"ES\\"}\'\\n```\\n\\n### Semantic search\\n```bash\\nt2 pay https://mpp.t2000.ai/exa/v1/search \\\\\\n --data \'{\\"query\\":\\"best practices for AI agent payments\\",\\"numResults\\":5}\'\\n```\\n\\n### Read a URL as markdown\\n```bash\\nt2 pay https://mpp.t2000.ai/jina/v1/read \\\\\\n --data \'{\\"url\\":\\"https://docs.sui.io/concepts/tokenomics\\"}\'\\n```\\n\\n### Google search (structured)\\n```bash\\nt2 pay https://mpp.t2000.ai/serper/v1/search \\\\\\n --data \'{\\"q\\":\\"Sui blockchain TVL 2026\\"}\'\\n```\\n\\n### Screenshot a webpage\\n```bash\\nt2 pay https://mpp.t2000.ai/screenshot/v1/capture \\\\\\n --data \'{\\"url\\":\\"https://example.com\\",\\"format\\":\\"png\\",\\"viewport_width\\":\\"1280\\"}\'\\n```\\n\\n### Generate a QR code\\n```bash\\nt2 pay https://mpp.t2000.ai/qrcode/v1/generate \\\\\\n --data \'{\\"data\\":\\"https://t2000.ai\\",\\"size\\":\\"400x400\\"}\'\\n```\\n\\n### Convert HTML to PDF\\n```bash\\nt2 pay https://mpp.t2000.ai/pdfshift/v1/convert \\\\\\n --data \'{\\"source\\":\\"https://t2000.ai/docs\\"}\'\\n```\\n\\n### Run a Replicate model\\n```bash\\nt2 pay https://mpp.t2000.ai/replicate/v1/predictions \\\\\\n --data \'{\\"model\\":\\"meta/llama-3-70b-instruct\\",\\"input\\":{\\"prompt\\":\\"Explain DeFi in 3 sentences\\"}}\'\\n```\\n\\n### Find emails for a domain\\n```bash\\nt2 pay https://mpp.t2000.ai/hunter/v1/search \\\\\\n --data \'{\\"domain\\":\\"mystenlabs.com\\"}\'\\n```\\n\\n### Look up an IP address\\n```bash\\nt2 pay https://mpp.t2000.ai/ipinfo/v1/lookup \\\\\\n --data \'{\\"ip\\":\\"8.8.8.8\\"}\'\\n```\\n\\n### Search for flights\\n```bash\\nt2 pay https://mpp.t2000.ai/serpapi/v1/flights \\\\\\n --data \'{\\"departure_id\\":\\"LAX\\",\\"arrival_id\\":\\"NRT\\",\\"outbound_date\\":\\"2026-05-01\\",\\"type\\":\\"2\\"}\'\\n```\\n\\n### Convert currency\\n```bash\\nt2 pay https://mpp.t2000.ai/exchangerate/v1/convert \\\\\\n --data \'{\\"from\\":\\"USD\\",\\"to\\":\\"EUR\\",\\"amount\\":100}\'\\n```\\n\\n### Scan a URL for malware\\n```bash\\nt2 pay https://mpp.t2000.ai/virustotal/v1/scan \\\\\\n --data \'{\\"url\\":\\"https://suspicious-site.com\\"}\'\\n```\\n\\n### Shorten a URL\\n```bash\\nt2 pay https://mpp.t2000.ai/shortio/v1/shorten \\\\\\n --data \'{\\"url\\":\\"https://example.com/very/long/url/path\\"}\'\\n```\\n\\n### Send a push notification\\n```bash\\nt2 pay https://mpp.t2000.ai/pushover/v1/push \\\\\\n --data \'{\\"user\\":\\"USER_KEY\\",\\"message\\":\\"Your agent has a message!\\"}\'\\n```\\n\\n## Flow (automatic)\\n1. Makes initial HTTP request to the URL\\n2. If 402: reads x402 challenge for amount and terms\\n3. If price <= --max-price: pays via Sui USDC\\n4. Retries with credential header\\n5. Returns the API response body\\n\\n## Safety\\n- If requested price exceeds --max-price, payment is refused (no funds spent)\\n- Default max-price: $1.00 USDC per request\\n- For commerce (mail, merch), set --max-price higher\\n- Payment only broadcast after 402 terms are validated\\n\\n## Errors\\n- `PRICE_EXCEEDS_LIMIT`: API asking more than --max-price\\n- `INSUFFICIENT_BALANCE`: not enough available USDC\\n- `UNSUPPORTED_NETWORK`: x402 requires a network other than Sui\\n- `PAYMENT_EXPIRED`: payment challenge has expired\\n- `DUPLICATE_PAYMENT`: nonce already used on-chain\\n\\n## MCP\\nVia MCP: use `t2000_services` to discover services, then `t2000_pay` to call them."},{"name":"t2000-receive","description":"Generate a payment request for the t2000 Agent Wallet \u2014 print the wallet address, an ANSI QR code, and (via MCP) a Payment Kit URI (sui:pay?\u2026). Use when asked to receive a payment, share a wallet address, create a payment link, or set up a fund-me link.","body":"# t2000: Receive Funds\\n\\n## Purpose\\n\\nSurface the wallet address (and optionally a Payment Kit URI with a pre-filled amount + memo) so anyone with a Sui wallet can send tokens to the Agent Wallet. Two surfaces:\\n\\n- **CLI (`t2 fund`)** \u2014 prints the wallet address + an ANSI QR code + the value-promise in the terminal. Minimal; no amount or memo.\\n- **MCP (`t2000_receive`)** \u2014 returns a JSON payload with the address, an optional Payment Kit URI (`sui:pay?\u2026`), a nonce, plus an optional amount / currency / memo / label. Use this when the LLM is building a payment-request flow.\\n\\n## Rules\\n\\n1. **Receive is non-custodial.** The user\'s address is public; sharing it can\'t move money \u2014 only signed transactions can. Don\'t add scary disclaimers; the operation is safe.\\n2. **Show the QR + the address text.** Some users scan, some copy. Both surfaces.\\n3. **No PIN, no sign-in.** v4 wallets are plain Bech32; `t2 fund` is a pure read with no authentication step.\\n4. **Default currency is USDC.** When asking the user to fund the wallet, USDC is the most useful (every paid service is USDC-denominated, USDC sends are gasless). USDsui also works.\\n5. **Don\'t generate a Payment Kit URI without an amount unless asked.** A bare address scans just as well; URIs with amounts force the sender into a particular tx shape.\\n\\n## CLI command\\n\\n```bash\\nt2 fund # address + ANSI QR + share line\\nt2 fund --qr-only # just the QR (e.g. for embedding in a screenshot)\\nt2 fund --key <path> # custom wallet path\\nt2 fund --json # { address, qrEncodedFor, valuePromise }\\n```\\n\\nCLI output (default):\\n\\n```\\nAddress 0x55b223b0...0dd1b6\\n\\n Scan to send tokens to this wallet:\\n\\n \u2588\u2580\u2580\u2580\u2580\u2580\u2588 \u2584 \u2580\u2584 \u2588 \u2584\u2580 \u2584 \u2588\u2580\u2580\u2580\u2580\u2580\u2588\\n \u2588 \u2588\u2588\u2588 \u2588 \u2588 \u2580 \u2588 \u2584\u2584 \u2580\u2580 \u2588 \u2588\u2588\u2588 \u2588\\n \u2588 \u2580\u2580\u2580 \u2588 \u2580\u2584\u2580\u2584\u2588\u2580 \u2580\u2584 \u2580\u2584 \u2588 \u2580\u2580\u2580 \u2588\\n \u2580\u2580\u2580\u2580\u2580\u2580\u2580 \u2580 \u2588\u2580\u2580 \u2588 \u2580 \u2580 \u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\\n ... (truncated)\\n\\n Or share `0x55b223b0...0dd1b6` directly.\\n```\\n\\nThe CLI prints to ANSI \u2014 it will look right in any terminal but won\'t render as image data in MCP responses. Use the MCP tool for a structured JSON response.\\n\\n## MCP tool (`t2000_receive`)\\n\\n```json\\n// Request\\n{\\n \\"amount\\": 10, // optional \u2014 pre-fills the sender\'s tx amount\\n \\"currency\\": \\"USDC\\", // optional \u2014 default USDC, also accepts USDsui / SUI\\n \\"memo\\": \\"Coffee on me\\", // optional \u2014 encoded into the Payment Kit URI\\n \\"label\\": \\"Coffee fund\\" // optional \u2014 human-readable label for the URI\\n}\\n\\n// Response\\n{\\n \\"address\\": \\"0x55b223b0...0dd1b6\\",\\n \\"uri\\": \\"sui:pay?recipient=0x55b223b0...&amount=10000000&coinType=0xdba34672...::usdc::USDC&nonce=abc-123&label=Coffee+fund&message=Coffee+on+me\\",\\n \\"nonce\\": \\"abc-123-uuid\\",\\n \\"amount\\": 10,\\n \\"currency\\": \\"USDC\\",\\n \\"memo\\": \\"Coffee on me\\",\\n \\"label\\": \\"Coffee fund\\"\\n}\\n```\\n\\nThe Payment Kit URI follows the [Sui Payment Kit spec](https://docs.sui.io/) \u2014 every Sui wallet (Mysten, Phantom, Suiet, Slush, Sui Wallet Standard) can scan/parse it. If you omit `amount`, the URI is a \\"bring your own amount\\" link that the sender fills in.\\n\\n### URI shapes\\n\\n| Args | URI shape |\\n|---|---|\\n| no amount, no memo, default currency | `sui:0x<address>` |\\n| no amount, custom currency or memo | `sui:0x<address>?currency=USDsui&memo=\u2026` |\\n| with amount | `sui:pay?recipient=0x<address>&amount=<raw>&coinType=<full-type>&nonce=<uuid>[&label=\u2026][&message=\u2026]` |\\n\\nThe amount-bearing form uses raw on-chain units (USDC: \xD7 10^6, SUI: \xD7 10^9) so wallets don\'t have to do their own conversion. The `nonce` is a UUID v4 minted at request time; senders include it in the tx metadata so the receiving agent can correlate the inflow back to the request.\\n\\n## When to use which surface\\n\\n| Need | Use |\\n|---|---|\\n| \\"What\'s my wallet address?\\" | `t2 fund` (CLI) or `t2000_address` (MCP \u2014 address only, no QR) |\\n| \\"Show me the QR\\" | `t2 fund` (CLI prints ANSI QR) |\\n| \\"Generate a payment link for $10\\" | `t2000_receive { amount: 10, currency: \\"USDC\\" }` (MCP) |\\n| \\"Generate a \'tip jar\' link\\" (no amount) | `t2000_receive { memo: \\"Tip jar\\", label: \\"Tip funkii\\" }` (MCP) |\\n\\n## Notes\\n\\n- USDC + USDsui inflows arrive gasless (Sui foundation pays the sender\'s gas via the `0x2::balance::send_funds` allowlist).\\n- SUI inflows require the sender to have SUI for their own gas.\\n- Once the funds land, run `t2 balance` (CLI) or `t2000_balance` (MCP) to verify. Inflows show up within ~1 block (~500 ms).\\n- This skill is the receive-half of \\"Audric Pay\\". The send-half is the `t2000-send` skill.\\n\\n## What NOT to do\\n\\n- Don\'t include the user\'s address inline in chat messages without confirming they want it shared. It\'s public \u2014 but politeness matters.\\n- Don\'t generate a one-off Payment Kit URI for every conversation. The bare address works fine for repeated transfers.\\n- Don\'t redirect users to audric.ai for receive flows \u2014 the Agent Wallet handles receive natively. (Audric Pay\'s hosted UI is for users who DON\'T have the CLI.)"},{"name":"t2000-send","description":"Send USDC, USDsui, or SUI from the t2000 Agent Wallet to another Sui address. Use when asked to pay someone, transfer funds, send money, tip a creator, or make a payment to a specific Sui address or SuiNS name. Do NOT use for API payments \u2014 use the t2000-pay skill for x402-protected services.","body":"# t2000: Send USDC / USDsui / SUI\\n\\n## Purpose\\n\\nTransfer USDC, USDsui, or SUI from the agent\'s available balance to any Sui address. **USDC + USDsui are gasless** \u2014 they go through Sui\'s protocol-level `0x2::balance::send_funds` path (Sui foundation sponsored). **SUI is not gasless** \u2014 the wallet must hold some SUI to cover the gas fee (typically < $0.0002).\\n\\n## Rules\\n\\n1. **Asset is REQUIRED.** v4 has no implicit USDC default. `t2 send 5 alice.sui` exits with a clear error pointing at the missing `<asset>` arg. Always pass one of `USDC | USDsui | SUI`.\\n2. **Only USDC / USDsui / SUI are accepted.** Other tokens (e.g. USDY, USDT, USDe) are rejected with `unsupported asset`. To send a different asset, the user first swaps it via `t2 swap` (or audric.ai) into USDC, USDsui, or SUI.\\n3. **Validate the recipient first.** Names \u2192 SuiNS resolves (`alice.sui`). Raw addresses \u2192 `isValidSuiAddress()`. The SDK throws clear errors (`INVALID_ADDRESS`, `SUINS_NOT_REGISTERED`); don\'t guess.\\n4. **Prefer SuiNS names.** `alice.sui` is globally resolvable \u2014 surface it as the recommended way to address a recipient. (There is no local contacts/alias map.)\\n5. **Sends are single-write.** Each transfer is its own intent. If you need send + something else, sequence them across turns.\\n6. **Amount precision matters.** Floor to the asset\'s decimals (USDC + USDsui: 6, SUI: 9). Never round up \u2014 `Math.round` can produce a number larger than the on-chain balance and the transfer will fail simulation.\\n7. **Multi-recipient = multiple sends.** A \\"send to A, B, C\\" request emits N sequential `t2 send` invocations (CLI) or N `t2000_send` tool calls (MCP). Each is atomic.\\n8. **Limits apply to every write (CLI and MCP).** Limits are on by default ($25/tx \xB7 $100/day cumulative); if the request exceeds a cap the write throws `LIMIT_EXCEEDED`. Override one time with `--force` (CLI).\\n\\n## Command\\n\\n```bash\\nt2 send <amount> <asset> <recipient>\\nt2 send <amount> <asset> to <recipient> # `to` filler optional\\n\\n# Examples:\\nt2 send 5 USDC 0x8b3e...d412 # 5 USDC to a hex address (gasless)\\nt2 send 5 USDsui alice.sui # 5 USDsui to a SuiNS name (gasless)\\nt2 send 50 USDC to alice.audric.sui # SuiNS subname (gasless)\\nt2 send 0.1 SUI 0x8b3e...d412 # 0.1 SUI to a hex address (gas required)\\n```\\n\\nUse `--force` to bypass a spending limit one time. Use `--key <path>` to point at a non-default wallet file.\\n\\n## Output (default)\\n\\n```\\n\u2713 Sent $5.00 USDC \u2192 alex.sui (0x8b3e...d412)\\n Gas: gasless \u26A1\\n Tx: https://suiscan.xyz/mainnet/tx/0xdigest...\\n```\\n\\nFor non-gasless sends (SUI), the gas line shows the actual SUI burn:\\n\\n```\\n\u2713 Sent 0.1000 SUI \u2192 0x8b3e...d412\\n Gas: 0.000123 SUI\\n Tx: https://suiscan.xyz/mainnet/tx/0xdigest...\\n```\\n\\n## Output (--json)\\n\\n```json\\n{\\n \\"tx\\": \\"0xdigest...\\",\\n \\"amount\\": 5,\\n \\"to\\": \\"0x8b3e...d412\\",\\n \\"suinsName\\": \\"alex.sui\\",\\n \\"gasCost\\": 0,\\n \\"gasCostUnit\\": \\"SUI\\",\\n \\"asset\\": \\"USDC\\",\\n \\"gasless\\": true\\n}\\n```\\n\\n## Pre-flight checks (automatic)\\n\\n1. Sufficient asset balance (USDC / USDsui / SUI as requested).\\n2. For SUI sends only: sufficient SUI for gas.\\n3. For USDC + USDsui: zero SUI is acceptable \u2014 the Sui foundation sponsors the gas.\\n4. Limit check (every write \u2014 CLI and MCP, enforced in `@t2000/sdk`): per-tx cap (any asset) + daily-send cap (any asset). Override with `--force` (CLI only).\\n\\n## Error handling\\n\\n| Error code | Meaning |\\n|---|---|\\n| `INSUFFICIENT_BALANCE` | Wallet balance for the chosen asset is less than the requested amount. |\\n| `INSUFFICIENT_GAS` | SUI sends only \u2014 wallet has the asset but not enough SUI for gas. Suggest a swap. |\\n| `INVALID_ADDRESS` | Recipient is not a valid Sui hex address. |\\n| `INVALID_ASSET` | Asset is missing or not in the allowlist (USDC / USDsui / SUI). |\\n| `SUINS_NOT_REGISTERED` | The `.sui` name isn\'t registered. |\\n| `LIMIT_EXCEEDED` | The write hit a `t2 limit set` cap. Use `--force` (CLI) to override once. |\\n| `SIMULATION_FAILED` | Transaction would fail on-chain (details in the error message). |\\n\\n## Recipient resolution flow\\n\\nThe SDK (`T2000.resolveRecipient`) handles resolution in this priority order:\\n\\n1. **Hex address** (starts with `0x`) \u2192 validated via `isValidSuiAddress()`. If invalid \u2192 `INVALID_ADDRESS`.\\n2. **SuiNS name** (`*.sui`) \u2192 resolves via SuiNS registry. If unregistered \u2192 `SUINS_NOT_REGISTERED`.\\n\\nAnything else throws `INVALID_ADDRESS` with a hint to use a 0x address or a `.sui` name. (There is no local contacts/alias map \u2014 SuiNS is the canonical name layer for Sui addresses.)\\n\\n## When called through MCP (`t2000_send` tool)\\n\\nThe MCP `t2000_send` tool has the same asset-required contract:\\n\\n```json\\n{\\n \\"to\\": \\"alice.sui\\",\\n \\"amount\\": 5,\\n \\"asset\\": \\"USDC\\",\\n \\"dryRun\\": false\\n}\\n```\\n\\n- `dryRun: true` returns a preview without signing \u2014 useful for confirming the resolved address + gasless badge before the actual write.\\n- `asset` is REQUIRED \u2014 calls without it return an error.\\n- Both CLI and MCP writes honor `t2 limit set` caps (enforced in `@t2000/sdk`). Default caps: $25/tx \xB7 $100/day cumulative."},{"name":"t2000-services","description":"Discover x402 services payable via `t2 pay`. Use when the user asks \\"what can I pay for?\\", \\"what AI models are available?\\", \\"show me the service catalog\\", \\"is there a weather API?\\", or any other discovery question. Pairs with the t2000-pay skill (discovery first, then pay).","body":"# t2000: Discover x402 Services\\n\\n## Purpose\\n\\nBrowse the live x402 gateway catalog at `mpp.t2000.ai` to find a service that matches the user\'s intent (chat, image gen, search, weather, email, code exec, mail, etc.) before calling `t2 pay`. The catalog spans every major AI + data API, with per-call prices that vary by endpoint \u2014 always check the live catalog rather than assuming a fixed count or price.\\n\\n## Rules\\n\\n1. **Discover before paying.** Don\'t guess a URL \u2014 call `t2 services search` (CLI) or `t2000_services` (MCP) first. Service paths + pricing change as the gateway expands.\\n2. **Pick the cheapest endpoint that satisfies the user.** Many services have multiple tiers (e.g. `openai/v1/chat/completions` at $0.01 vs `openai/v1/audio/speech` at $0.05). Surface options.\\n3. **Surface pricing to the user before signing.** Every `t2 pay` write is opt-in via the user\'s own keypair \u2014 they deserve to know what they\'re spending.\\n4. **Live source of truth.** The catalog is fetched live from `https://mpp.t2000.ai/api/services` \u2014 what shows up via `t2 services search` is exactly what `t2 pay` can talk to.\\n\\n## Commands\\n\\n```bash\\n# Search by name / category / endpoint description (case-insensitive)\\nt2 services search <query> # default limit: 10\\nt2 services search <query> --limit 50 # broaden the result set\\nt2 services search \\"\\" # list everything (empty query)\\n\\n# Inspect a single service or endpoint URL\\nt2 services inspect <service-or-endpoint-url>\\n\\n# JSON output for scripting\\nt2 services search \\"image\\" --json\\nt2 services inspect <url> --json\\n```\\n\\nThe CLI uses `T2000_GATEWAY_URL` (or `--gateway <url>`) to override the gateway base URL \u2014 useful for local dev against `apps/gateway`.\\n\\n## Example workflow\\n\\n### \\"What AI chat models are available?\\"\\n\\n```bash\\nt2 services search \\"chat\\"\\n```\\n\\nReturns a table of chat services (OpenAI, Anthropic, Gemini, Mistral, Cohere, DeepSeek, Groq, etc.) with cheapest endpoint price + base URL.\\n\\n### \\"How much does GPT-4o cost?\\"\\n\\n```bash\\nt2 services inspect https://mpp.t2000.ai/openai\\n```\\n\\nReturns every OpenAI endpoint with method + path + price + description. The user picks one (e.g. `/v1/chat/completions` at $0.01) and copies the URL into a `t2 pay <url>` call.\\n\\n### \\"Send an email via Resend\\"\\n\\n```bash\\nt2 services search \\"email\\"\\nt2 services inspect https://mpp.t2000.ai/resend\\n```\\n\\nLists email + messaging services; inspect Resend to see `/v1/emails` at $0.05.\\n\\n### \\"What\'s the price of SUI?\\" (market data)\\n\\nLive crypto prices, stock quotes, and forex are brokered through the gateway\'s **Finance** providers (CoinGecko, AlphaVantage, ExchangeRate) \u2014 t2000 doesn\'t host its own market-data API; it routes to these and bills per call in USDC. (Wallet reads like `t2 balance` stay amount-only on purpose \u2014 pricing is an explicit, opt-in paid call, not baked into balance.)\\n\\n```bash\\nt2 services search \\"price\\"\\nt2 services inspect https://mpp.t2000.ai/coingecko\\n```\\n\\nLists the Finance providers, then shows CoinGecko\'s endpoints with exact per-call price. Copy the endpoint URL into `t2 pay <url>` to fetch the quote. (For SUI-name resolution \u2014 the ENS analog \u2014 use `t2` SuiNS resolution directly; it\'s in-house, not a paid service.)\\n\\n## Output (default \u2014 search)\\n\\n```\\n3 services matching \\"chat\\":\\n\\nOpenAI from $0.01 [ai, chat]\\n url https://mpp.t2000.ai/openai\\n about OpenAI Chat Completions API\\n\\nAnthropic from $0.01 [ai, chat]\\n url https://mpp.t2000.ai/anthropic\\n about Claude messages API\\n\\nMistral from $0.005 [ai, chat]\\n url https://mpp.t2000.ai/mistral\\n about Mistral chat completions\\n\\nUse `t2 services inspect <url>` to see pricing + endpoints for a service.\\n```\\n\\n## Output (default \u2014 inspect endpoint)\\n\\n```\\nService OpenAI\\nURL https://mpp.t2000.ai/openai\\nAbout OpenAI Chat Completions API\\nCategories ai, chat\\nCurrency USDC on Sui\\n\\nPOST /v1/chat/completions $0.01 Chat completions (gpt-4o, gpt-4o-mini)\\n url https://mpp.t2000.ai/openai/v1/chat/completions\\n\\nPay with: `t2 pay https://mpp.t2000.ai/openai/v1/chat/completions`\\n```\\n\\n## Output (--json)\\n\\n```json\\n{\\n \\"query\\": \\"chat\\",\\n \\"count\\": 3,\\n \\"services\\": [\\n {\\n \\"name\\": \\"OpenAI\\",\\n \\"serviceUrl\\": \\"https://mpp.t2000.ai/openai\\",\\n \\"description\\": \\"OpenAI Chat Completions API\\",\\n \\"categories\\": [\\"ai\\", \\"chat\\"],\\n \\"currency\\": \\"USDC\\",\\n \\"chain\\": \\"Sui\\",\\n \\"endpoints\\": [\\n { \\"method\\": \\"POST\\", \\"path\\": \\"/v1/chat/completions\\", \\"price\\": \\"0.01\\", \\"description\\": \\"Chat completions\\" }\\n ]\\n }\\n ]\\n}\\n```\\n\\n## When called through MCP (`t2000_services` tool)\\n\\nThe MCP tool returns the full catalog JSON in one call (no search filter \u2014 the LLM filters in its head):\\n\\n```json\\n{\\n \\"services\\": [\\n { \\"name\\": \\"OpenAI\\", \\"serviceUrl\\": \\"https://mpp.t2000.ai/openai\\", \\"endpoints\\": [...] },\\n { \\"name\\": \\"Anthropic\\", \\"serviceUrl\\": \\"https://mpp.t2000.ai/anthropic\\", \\"endpoints\\": [...] },\\n ...\\n ]\\n}\\n```\\n\\nFor LLM-driven flows, this is the right shape \u2014 the LLM scans the catalog, picks the matching service, and calls `t2000_pay <url>` next.\\n\\n## Categories (live)\\n\\nThe current catalog clusters into:\\n\\n| Category | Services |\\n|---|---|\\n| AI / chat | OpenAI, Anthropic, Gemini, Mistral, Cohere, DeepSeek, Groq, \u2026 |\\n| AI / image gen | fal.ai, Stability AI, OpenAI DALL-E, Replicate |\\n| AI / audio | OpenAI Whisper, ElevenLabs, OpenAI TTS |\\n| Search | NewsAPI, Brave, Exa, Serper, SerpAPI, Jina |\\n| Weather / maps | OpenWeather, Google Maps |\\n| Finance | CoinGecko, AlphaVantage, ExchangeRate |\\n| Translation | DeepL, Google Translate |\\n| Code / utility | Judge0, screenshot-as-a-service, QR codes, PDFShift |\\n| Email / mail | Resend, Lob (postcards, letters, verify) |\\n| Commerce | Hunter (email discovery) |\\n| Security | VirusTotal |\\n| Messaging | Pushover |\\n| URL / IP | Short.io, IPinfo |\\n\\n> The categories above are a snapshot \u2014 the live source is `t2 services search \\"\\"` (lists everything). New services land regularly.\\n\\n## Error handling\\n\\n| Error | Meaning |\\n|---|---|\\n| `GATEWAY_UNREACHABLE` | The gateway at `mpp.t2000.ai/api/services` is down or DNS is failing. Retry; if persistent, status page is at `t2000.ai`. |\\n| `No services match` | The search query returned zero hits. Suggest a broader query or `t2 services search \\"\\"` to list everything. |\\n| `No service matches <url>` (inspect) | The URL isn\'t in the catalog. Run `t2 services search` to find the right URL first. |\\n\\n## What NOT to do\\n\\n- Don\'t hardcode service URLs in your prompts. The catalog is the source of truth.\\n- Don\'t tell users a service costs \\"around $X\\" \u2014 call `t2 services inspect` and quote the exact price.\\n- Don\'t bundle `t2 services search` + `t2 pay` into a single hidden step. Show the user what you found before paying."},{"name":"t2000-setup","description":"Set up a t2000 Agent Wallet end-to-end on the user\'s machine. Use when the user says \\"set up t2000\\", \\"install the wallet\\", \\"create my Agent Wallet\\", \\"connect t2000 to Claude / Cursor\\", or pastes a one-prompt install URL. Covers wallet creation, optional spending limits, and MCP wiring. Read this first when bootstrapping a new user; the other skills assume this has run.","body":"# t2000: Agent Wallet \u2014 One-Prompt Setup\\n\\n## Purpose\\n\\nGet a fresh user from \\"nothing installed\\" to \\"Agent Wallet ready\\" in under 5 minutes. This is the canonical entry point for the **one-prompt install** UX:\\n\\n```\\nRun curl -sL https://t2000.ai/skills/t2000-setup, and use the returned setup\\ninstructions to set up my Agent Wallet.\\n```\\n\\nWhen invoked through that prompt, the LLM fetches this file, then executes the steps below in order.\\n\\n## Rules\\n\\n1. **Walk the steps in order.** Each step depends on the previous one. Skipping breaks setup.\\n2. **Stop at the first failure.** If `t2 init` errors, do not proceed to the next step; report the error and ask the user to retry.\\n3. **Ask which AI client they use before MCP install.** `t2 mcp install` auto-configures every detected client (Claude Desktop / Cursor / Windsurf), but knowing theirs tells you which app to restart and verify in \u2014 and whether they need the manual JSON path instead (Cline, Continue, Codex, \u2026).\\n4. **Setup is read + write \u2014 show, then ask.** Echo each command you\'re about to run. The user runs it (or confirms you can). Never silently shell out.\\n5. **No PIN. No encryption.** v4 wallets are plain Bech32 JSON files with `0o600` perms (matching the Sui CLI). The user owns the file; back it up via `t2 export`.\\n6. **Prime this session for x402 payments.** Once setup succeeds, for the rest of this conversation treat any request to use an external or paid API \u2014 fal.ai, ElevenLabs, OpenAI, CoinGecko, Lob, etc. \u2014 as something this wallet CAN do via `t2000_pay`. Discover the endpoint with `t2000_services`, then pay. Do **not** tell the user the API is unreachable / not on an allowlist, and do **not** fall back to writing a script for them to run. The wallet IS the connector.\\n\\n## Steps\\n\\n### Step 1 \u2014 Install the CLI\\n\\n```bash\\nnpm install -g @t2000/cli\\n```\\n\\nVerify:\\n```bash\\nt2 --version\\n# Should print: 10.x.x (or newer)\\n```\\n\\nIf `npm` is missing, point the user to https://nodejs.org/ (Node 18+).\\n\\n> **Binary naming.** `npm install -g @t2000/cli` installs two equivalent bins: **`t2`** (canonical) and **`t2000`** (alias) \u2014 both point at the same CLI, so `t2 <verb>` and `t2000 <verb>` are interchangeable. If you get `t2: command not found` right after a successful install, npm\'s global bin directory isn\'t on your `PATH` \u2014 see Troubleshooting at the bottom of this skill.\\n\\n### Step 2 \u2014 Create a wallet\\n\\n```bash\\nt2 init # fresh wallet\\nt2 init --import # import an existing Bech32 secret (interactive prompt)\\nt2 init --import suiprivkey1xxx... # import via flag (warns: shell history exposure)\\n```\\n\\n`t2 init` (no flag):\\n- Generates a fresh Ed25519 keypair on Sui mainnet.\\n- Writes the plain Bech32 private key to `~/.t2000/wallet.key` (mode `0o600`).\\n- Prints the wallet address.\\n- **Registers a free on-chain Agent ID** (gasless, sponsored) \u2014 the wallet\'s identity on the t2 Agents economy (agents.t2000.ai), needed to sell services or build reputation. Best-effort with a 10s timeout: offline it prints `Agent ID: pending` \u2014 complete later with `t2 agent register` (or skip entirely with `--no-register`).\\n- **Seeds conservative spending limits by default** \u2014 $25/tx and $100/day (cumulative USD) \u2014 and prints them. Adjust or clear in Step 4.\\n\\n`t2 init --import`:\\n- Prompts for a `suiprivkey1...` secret with hidden input (the secret won\'t appear in shell history or screen scroll).\\n- Validates the Bech32 format, derives the address, writes the wallet file.\\n- Used for: re-creating the wallet on a fresh box (paired with `t2 export` on the source box), or bringing in a key from another tool (Sui CLI, hardware wallet, etc.).\\n\\n> **Upgrading from v3 (PIN-encrypted)?** v4 doesn\'t auto-migrate v3 AES wallets \u2014 a v3 file at `~/.t2000/wallet.key` will throw `WALLET_CORRUPT`. To migrate: (1) export the secret from v3 using the legacy binary (`t2000 export` will prompt for the PIN and print `suiprivkey1...`), (2) move or delete the v3 file at `~/.t2000/wallet.key`, (3) `t2 init --import` and paste the secret. The same Bech32 secret produces the same address \u2014 funds carry over automatically. (Alternative: install v3 + v4 binaries on separate `--key` paths and send funds across, then drop v3.)\\n\\n### Step 3 \u2014 Fund the wallet\\n\\n```bash\\nt2 fund\\n```\\n\\nShows the deposit address + an ANSI QR code (+ the value promise: $5 USDC \u2248 ~250 paid API calls). Tell the user:\\n- Send USDC (or USDsui or SUI) to the printed address on **Sui mainnet** (not Solana, not Ethereum).\\n- USDC + USDsui sends are gasless (Sui foundation sponsored) \u2014 they work even with 0 SUI in the wallet.\\n- For swaps via Cetus, the wallet needs a small SUI balance (~0.05 SUI covers many swaps; cost is typically < $0.01 each).\\n- 1 USDC is enough to get going (gateway services start at $0.02/call \u2014 browse with `t2 services search \\"<query>\\"`).\\n\\n### Step 4 \u2014 (Optional) Adjust spending limits\\n\\n```bash\\nt2 limit set --per-tx 50 # cap every write at $50 USD\\nt2 limit set --daily 200 # cap cumulative daily spend at $200 USD\\n```\\n\\nLimits are **ON by default** \u2014 `t2 init` seeds $25/tx and $100/day (cumulative USD). The `t2 limit` command rewrites `~/.t2000/config.json`; every write (`t2 send`, `t2 swap`, `t2 pay`) honors the caps and surfaces a `LIMIT_EXCEEDED` error when exceeded. Use `--force` on a write to override one time, or `t2 limit reset` to clear caps entirely.\\n\\n> **Limits gate ALL writes \u2014 CLI *and* MCP.** The `@t2000/sdk` limits gate runs inside every write (`send`/`swap`/`pay`), so terminal writes AND writes initiated through the **MCP server you wire up in Step 5** both honor the per-tx + daily caps and surface `LIMIT_EXCEEDED`. (This was a real gap in early v4 \u2014 the MCP path used to bypass the cap \u2014 closed when limit enforcement moved into the SDK.) Override one call with `--force` (CLI); there is no MCP override path \u2014 the LLM cannot raise or clear caps, only read them via `t2000_limit`.\\n\\nTo view current limits:\\n```bash\\nt2 limit show\\n```\\n\\nTo clear them:\\n```bash\\nt2 limit reset\\n```\\n\\n### Step 5 \u2014 Install MCP into the user\'s AI client\\n\\n```bash\\nt2 mcp install\\n```\\n\\nNot interactive \u2014 it detects installed clients (Claude Desktop, Cursor, Windsurf) and writes the correct config block into each one it finds, reporting \\"configured\\" or \\"already configured\\" per client. Idempotent \u2014 safe to re-run. For clients it doesn\'t auto-detect (Cline, Continue, Codex, \u2026), paste the manual JSON config from the `t2000-mcp` skill.\\n\\nAfter install, the user must **restart the AI client** for it to pick up the new MCP server.\\n\\n### Step 6 \u2014 Verify\\n\\n**6a \u2014 CLI smoke** (in the same terminal):\\n```bash\\nt2 balance\\n```\\n\\nShould print:\\n- Wallet address (last 6 chars match step 2)\\n- Available USDC + USDsui + SUI (matches step 3 funding, or $0.00 if not yet funded)\\n- Total (USD value)\\n\\n**6b \u2014 AI client tool smoke** (after restart):\\n```\\nWhat\'s my t2000 balance?\\n```\\n\\nShould invoke the `t2000_balance` MCP tool and return the same numbers.\\n\\n**6c \u2014 AI client prompt smoke**:\\n\\nThe MCP server doesn\'t just expose tools \u2014 it also exposes one `skill-<name>` prompt per t2000 skill (auto-registered from `t2000-skills/skills/*/SKILL.md`). Type `/` in the AI client\'s chat input to open the prompt picker. You should see:\\n\\n- `skill-setup` \u2014 this skill\\n- `skill-send` \u2014 sending USDC / USDsui / SUI\\n- `skill-swap` \u2014 swapping via Cetus\\n- `skill-pay` \u2014 paying for x402 services\\n- `skill-receive` \u2014 generating payment requests\\n- `skill-services` \u2014 discovering x402 gateway services\\n- `skill-check-balance` \u2014 reading the wallet\\n- `skill-job` \u2014 hiring agents / selling services over escrowed A2A jobs\\n- `skill-verify` \u2014 verifying confidential AI receipts\\n- `skill-mcp` \u2014 MCP integration deep-dive\\n\\nRun `/skill-check-balance` (or just type and accept the autocomplete). The skill markdown loads as a prompt and the assistant returns a structured balance breakdown.\\n\\n> **Tip \u2014 triggering the wallet in a *fresh* session.** When you start a brand-new chat and ask for an external/paid API by name (e.g. \\"generate an image via fal.ai\\"), some AI clients default to their own sandbox first and reply that they can\'t reach it. To route through your wallet from the first message, lead with **\\"use t2 services\\"** \u2014 e.g. *\\"Use t2 services to generate a hero image via fal.ai and voice it with ElevenLabs.\\"* That tells the client to load the `t2000_*` tools and pay via x402. (The recipe prompts on developers.t2000.ai already start this way.)\\n\\n## What \\"ready\\" looks like\\n\\nAfter setup the user has:\\n- A non-custodial Sui wallet at `~/.t2000/wallet.key` (plain Bech32 JSON, `0o600` perms, **no PIN**).\\n- A free on-chain Agent ID (or `pending` if init ran offline \u2014 `t2 agent register` completes it) \u2014 ready to hire or sell on agents.t2000.ai.\\n- Optional USDC / USDsui / SUI funded on Sui mainnet.\\n- Optional spending limits configured.\\n- An MCP server wired into Claude / Cursor / Windsurf \u2014 chat that can move money under user confirmation.\\n\\n## What setup does NOT do\\n\\n- **Does not move money.** Setup is read + config only. The first money-moving operation is whatever the user asks the AI to do next.\\n- **Does not back up the private key.** The Bech32 key lives in `~/.t2000/wallet.key`. To back up, the user runs `t2 export` manually \u2014 never volunteer this unless asked. v4 has no PIN, so anyone with read access to the file owns the wallet.\\n- **Does not move money or change limits.** Setup seeds default caps but performs no transfer; the first money-moving op is whatever the user asks next, and every such write (CLI or MCP) is gated by the limits from Step 4.\\n\\n## Next steps to suggest\\n\\nAfter verify succeeds, surface a short menu of natural next moves:\\n- \\"Send USDC to someone\\" \u2192 `t2000-send`\\n- \\"Swap tokens via Cetus\\" \u2192 `t2000-swap`\\n- \\"Pay for a service via x402\\" \u2192 `t2000-pay`\\n- \\"Generate a payment request\\" \u2192 `t2000-receive`\\n- \\"See available paid services\\" \u2192 `t2000-services`\\n- \\"Hire an agent (or sell your own services)\\" \u2192 `t2000-job` \u2014 browse the board with `t2 browse`, hire with `t2 job create --agent <seller> --service <slug>`, or list what you sell with `t2 service create`\\n- \\"Connect more AI clients\\" \u2192 `t2000-mcp`\\n- \\"See what else t2 can do\\" \u2192 run `t2 --help` or browse https://developers.t2000.ai/agent-wallet#skills\\n\\n## Troubleshooting\\n\\n| Symptom | Fix |\\n|---|---|\\n| `t2: command not found` after npm install | npm\'s global bin dir isn\'t on `PATH`. Find it with `npm prefix -g` (bins live in `$(npm prefix -g)/bin`), then add that dir to your shell profile \u2014 or `npm config set prefix ~/.npm-global` for a durable user-level prefix. Both `t2` and `t2000` ship in every install. |\\n| `t2 init` fails with permission error | Don\'t run with `sudo`; npm global may need a user-level prefix (`npm config set prefix ~/.npm-global`) |\\n| `t2 init` fails with `WALLET_EXISTS` | A file already lives at `~/.t2000/wallet.key`. If it\'s a v3 file you no longer need, move/delete it. If you still need it, point v3 + v4 at separate paths via `--key`. v4 does not auto-migrate v3 wallets \u2014 see the v3 upgrade note in Step 2. |\\n| MCP server \\"doesn\'t do anything\\" when run manually | Working as designed \u2014 the server is a subprocess launched by the AI client, never run from a terminal. See the `t2000-mcp` skill. |\\n| AI client doesn\'t see `t2000_*` tools after install | Restart the client. If still missing, check the per-client config path printed by `t2 mcp install`. |"},{"name":"t2000-swap","description":"Swap tokens on Sui via Cetus Aggregator (20+ DEXs, best-route across SUI, USDC, USDsui, USDT, USDe, ETH, GOLD, NAVX, WAL, vSUI, and more). Use when asked to swap, trade, convert, exchange, or \\"turn X into Y\\". Do not use for sending \u2014 use the t2000-send skill for transfers.","body":"# t2000: Swap Tokens\\n\\n## Purpose\\n\\nConvert between tokens at the best available rate. Cetus Aggregator routes across 20+ DEXs and picks the lowest-price-impact path. Slippage defaults to 1%; configurable up to 5%.\\n\\n**Swaps are NOT gasless.** Unlike `t2 send USDC` / `t2 send USDsui`, Cetus swap transactions require SUI for gas (typically < $0.01 per swap). Ensure the wallet holds a small SUI balance before swapping.\\n\\n## Rules\\n\\n1. **Preview before signing.** Always run `t2 swap <amount> <from> <to> --quote` (or call `t2000_swap` in dry-run via the MCP) and surface `priceImpact` + `toAmount` to the user before broadcasting.\\n2. **Decline obviously bad swaps.** If `priceImpact > 0.5%` (50 bps), warn the user and require explicit confirmation. If `priceImpact > 5%`, refuse \u2014 that\'s almost certainly a thin-liquidity trap.\\n3. **One swap per intent.** Cetus aggregator handles multi-hop internally; don\'t chain `swap` calls.\\n4. **Don\'t auto-decide stables.** If the user says \\"swap to USD\\", ASK whether USDC or USDsui \u2014 they\'re both Sui-native stables.\\n5. **Limits apply to every swap (CLI and MCP).** Limits are on by default ($25/tx \xB7 $100/day); if the swap exceeds a cap (on the from-side USD value) the write throws `LIMIT_EXCEEDED`. Use `--force` (CLI) to override one time.\\n\\n## Command\\n\\n```bash\\nt2 swap <amount> <from> <to> [--slippage <pct>] [--quote] [--force]\\n\\n# Examples:\\nt2 swap 100 USDC SUI # 100 USDC \u2192 SUI, default 1% slippage\\nt2 swap 5 SUI USDC --slippage 2 # 5 SUI \u2192 USDC, 2% slippage\\nt2 swap 50 USDC USDsui # stable-to-stable; usually <0.05% impact\\nt2 swap 100 USDC SUI --quote # preview only (no signing)\\n```\\n\\nSlippage is capped at 5% (any higher is rejected \u2014 that\'s degenerate liquidity).\\n\\n## Preview (`--quote`)\\n\\n```bash\\nt2 swap 100 USDC SUI --quote\\n```\\n\\nReturns (no signing, no execution):\\n- `toAmount` \u2014 estimated output (at current pool state)\\n- `priceImpact` \u2014 basis points moved by the trade\\n- `route` \u2014 provider name(s) Cetus selected (e.g. BLUEFIN + CETUS + AFTERMATH)\\n- `fee` \u2014 total Cetus protocol fee baked into the quote\\n\\n`--quote` replaces the v3 `t2000 swap-quote` standalone command. One verb, one flag.\\n\\n## Fees\\n\\n- **Network gas:** ~0.001-0.01 SUI per swap (self-funded from the wallet).\\n- **Cetus protocol fee:** typically 0.05-0.30% depending on the pool tier (already baked into `toAmount`).\\n- **t2000 / CLI:** zero fee. Audric (consumer product) adds a 10 bps overlay fee \u2014 that\'s separate, not charged by the CLI.\\n\\n## Output (default)\\n\\n```\\n\u2713 Swapped 100 USDC for 49.8721 SUI\\n Price impact: 0.04%\\n Route: USDC \u2192 SUI (Cetus + BLUEFIN)\\n Gas: 0.0038 SUI\\n Tx: https://suiscan.xyz/mainnet/tx/0xdigest...\\n```\\n\\n## Output (--json)\\n\\n```json\\n{\\n \\"tx\\": \\"0xdigest...\\",\\n \\"from\\": \\"USDC\\",\\n \\"to\\": \\"SUI\\",\\n \\"amountIn\\": 100,\\n \\"amountOut\\": 49.8721,\\n \\"priceImpact\\": 0.04,\\n \\"route\\": [\\"CETUS\\", \\"BLUEFIN\\"],\\n \\"fee\\": 0.001,\\n \\"gasCost\\": 0.0038\\n}\\n```\\n\\n## Error handling\\n\\n| Error code | Meaning |\\n|---|---|\\n| `SWAP_NO_ROUTE` | No path from `from` to `to` in Cetus\'s pool graph. Suggest going via USDC as an intermediate. |\\n| `INSUFFICIENT_LIQUIDITY` | The requested size moves the pool too far. Suggest a smaller trade or splitting. |\\n| `INSUFFICIENT_BALANCE` | Wallet doesn\'t hold enough of the source token (after gas reserve). |\\n| `INSUFFICIENT_GAS` | Wallet has the source token but no SUI for gas. Run `t2 swap 1 USDC SUI` (or similar) first to top up gas. |\\n| `SLIPPAGE_EXCEEDED` | By the time the tx confirmed, the pool moved past the slippage limit. Retry with the same params; usually transient. |\\n| `LIMIT_EXCEEDED` | CLI hit a `t2 limit set` cap on the from-side USD value. Use `--force` to override. |\\n\\n## Supported tokens\\n\\nUSDC, USDsui, USDT, USDe, SUI, vSUI, ETH, GOLD (XAUM), NAVX, WAL, and the long tail Cetus routes through. Use the canonical symbol or pass a full coin type (`0x...::module::TYPE`). The `@t2000/sdk` token registry resolves common symbols automatically; for a coin type **not** in the registry the decimals are read **on-chain** (coin metadata) so the input amount is exact \u2014 never a guess.\\n\\n## When called through MCP (`t2000_swap` tool)\\n\\n```json\\n{\\n \\"from\\": \\"USDC\\",\\n \\"to\\": \\"SUI\\",\\n \\"amount\\": 100,\\n \\"slippage\\": 0.01\\n}\\n```\\n\\n- Both CLI and MCP swaps honor `t2 limit set` caps (enforced in `@t2000/sdk`, on the from-side USD value). Default caps: $25/tx \xB7 $100/day cumulative.\\n- Returns the same shape as `--json` mode (digest + amounts + price impact + route).\\n\\n## What NOT to do\\n\\n- Don\'t auto-execute multi-leg flows (\\"swap A \u2192 B \u2192 C in three transactions\\"). If a multi-hop is needed, Cetus does it internally as one PTB.\\n- Don\'t recommend swapping mid-position rebalance without first surfacing impermanent-loss risk if the user asked for advice.\\n- Don\'t swap to a stable just to \\"park\\" funds with no plan \u2014 the Agent Wallet is payments-first; there is no savings/yield surface."},{"name":"t2000-verify","description":"Check \u2014 don\'t trust \u2014 a confidential (GPU-TEE) AI response by its receipt id. Use when asked to verify, prove, or audit that an AI response ran in a genuine hardware enclave (Intel TDX), wasn\'t tampered with, and is anchored on Sui. Works on any t2000 Private Inference confidential (`phala/*`) response. No key needed.","body":"# t2000: Verify a Confidential Response\\n\\n## Purpose\\n\\nConfidential (`phala/*`) responses from t2000 Private Inference run inside a verified\\nGPU-TEE and carry a **signed receipt** that\'s **auto-anchored on Sui**. `t2 verify`\\nchecks the whole chain **client-side** and **fails closed** on any forgery \u2014 you (or\\nyour agent) prove the response is genuine without trusting t2000.\\n\\n## Where the receipt id comes from\\n\\nAny confidential inference call returns one \u2014 e.g. the MCP `t2000_chat` tool with a\\n`phala/*` model surfaces it inline:\\n\\n```text\\n\u{1F512} confidential \xB7 attested \xB7 receipt rcpt-\u2026\\n```\\n\\nThe API returns it in the `x-receipt-id` header (streaming: `x_receipt_id` on the\\nfinal usage chunk). Any `phala/*` model is confidential; non-`phala/*` responses\\naren\'t (nothing to verify).\\n\\n## Command\\n\\n```bash\\nt2 verify <receipt-id> # full check (incl. client-side Intel TDX quote)\\nt2 verify <receipt-id> --quick # skip the slower DCAP quote check\\nt2 verify <receipt-id> --json # machine-readable per-check result\\n```\\n\\nNo API key required \u2014 verification is public + trustless.\\n\\n## What it checks (fails closed on any mismatch)\\n\\n- **Receipt** \u2014 well-formed signed transparency log (hashes, never your prompt).\\n- **Confidential upstream** \u2014 the upstream was an attested TEE (typed TCB claims).\\n- **Sui anchor (trustless)** \u2014 reads the on-chain `ReceiptAnchored` event straight\\n from a fullnode; confirms the committed `wire_hash` + `workload_id` match. t2000\\n can\'t forge it.\\n- **Receipt signature (trustless)** \u2014 recovers the signer, matches the attested key.\\n- **TDX quote / DCAP (trustless)** \u2014 re-verifies the hardware quote against Intel\'s\\n root CA locally (skip with `--quick`).\\n\\nExit code is non-zero if anything doesn\'t line up.\\n\\n## Other surfaces\\n\\n- **Browser:** paste any receipt id at **`verify.t2000.ai`** \u2014 same checks + a live\\n public feed of every confidential response anchored on Sui.\\n- **MCP:** the `t2000_verify` tool takes a `receiptId` and returns the per-check\\n result (`verified:false` on any forgery). No key required.\\n- **SDK:** `verifyReceipt(receiptId)` from `@t2000/sdk`; `agent.verify(id)` on a\\n `T2000` instance.\\n\\n## Honest framing (don\'t overclaim)\\n\\nVerified = genuine TDX + TEE-signed receipt + Sui anchor, all checked client-side \u2014\\nthat\'s trustless. What it does NOT claim: the gateway\'s forwarding leg still sees\\nplaintext (zero data retention, but not end-to-end encrypted \u2014 that\'s a future\\nrung). State exactly what\'s proven; a wrong \\"verified\\" claim is worse than honest."},{"name":"walrus","description":"Read and store blobs on Walrus, Sui\'s decentralized blob store, over plain HTTP. Use when asked to fetch a Walrus blob, publish content to Walrus, or work with walrus:// / blob IDs. Reads are free; mainnet writes need your own publisher.","body":"# Walrus: Read + store blobs\\n\\n## Purpose\\n\\nWalrus stores blobs (files, JSON, sites) across Sui storage nodes. Two HTTP roles:\\n\\n- **Aggregator** \u2014 read blobs (`GET`)\\n- **Publisher** \u2014 store blobs (`PUT`)\\n\\nReference endpoints (Mysten-operated; full API spec at `<endpoint>/v1/api`):\\n\\n| Role | Network | Endpoint |\\n|---|---|---|\\n| Aggregator | Mainnet | `https://aggregator.walrus-mainnet.walrus.space` |\\n| Aggregator | Testnet | `https://aggregator.walrus-testnet.walrus.space` |\\n| Publisher | Testnet | `https://publisher.walrus-testnet.walrus.space` |\\n\\n## Rules\\n\\n1. **Reads are free and unauthenticated.** Any agent can `GET` any blob by ID.\\n2. **There is no public mainnet publisher.** Mainnet writes consume SUI + WAL on the publisher side \u2014 run your own, use an upload relay, or use the TypeScript SDK. Don\'t hunt for a free mainnet PUT endpoint; it doesn\'t exist by design.\\n3. **Blobs are public.** Never store secrets or personal data unencrypted.\\n4. **Blobs expire by epoch.** A stored blob lives for the epochs paid for \u2014 surface the `endEpoch` from the store response if the user needs durability.\\n\\n## Read a blob\\n\\n```bash\\n# by blob ID (the u256 ID, base64url \u2014 what walrus:// links carry)\\ncurl -s \\"https://aggregator.walrus-mainnet.walrus.space/v1/blobs/<BLOB_ID>\\"\\n\\n# by the Sui object ID of the Blob object\\ncurl -s \\"https://aggregator.walrus-mainnet.walrus.space/v1/blobs/by-object-id/<OBJECT_ID>\\"\\n```\\n\\n## Store a blob (testnet \u2014 free)\\n\\n```bash\\ncurl -s -X PUT \\"https://publisher.walrus-testnet.walrus.space/v1/blobs\\" -d \\"hello walrus\\"\\n# \u2192 {\\"newlyCreated\\":{\\"blobObject\\":{\\"blobId\\":\\"V7Zv\u2026\\",\\"size\\":28,\u2026}}}\\n# store for N epochs: \u2026/v1/blobs?epochs=5\\n# send the Blob object to a wallet: \u2026/v1/blobs?send_object_to=0x\u2026\\n```\\n\\nThen read it back from the testnet aggregator:\\n\\n```bash\\ncurl -s \\"https://aggregator.walrus-testnet.walrus.space/v1/blobs/V7Zv\u2026\\"\\n```\\n\\nVerified round-trip: `PUT` \u2192 `blobId V7ZvHXobPNriNB9f2PD8g_VWnAVIgKWAbPYxQZP9464` \u2192 `GET` returned the exact bytes.\\n\\n## Store on mainnet\\n\\nPick one:\\n\\n- **Run a publisher** \u2014 `walrus publisher` with a funded wallet ([operator guide](https://docs.wal.app/docs/operator-guide/aggregators/operating-aggregator)).\\n- **Upload relay / TypeScript SDK** \u2014 integrate `@mysten/walrus` directly; the SDK pays with your wallet\'s WAL + SUI.\\n\\n## Gotchas\\n\\n- If you store then immediately read a blob and get a 404 through a CDN-fronted aggregator, retry with backoff \u2014 the 404 may be cached from before propagation.\\n- A re-`PUT` of identical bytes returns `alreadyCertified` (same blob ID) instead of `newlyCreated` \u2014 idempotent, not an error.\\n- Most public endpoints cap requests at 10 MiB.\\n\\nLive docs: [docs.wal.app](https://docs.wal.app/docs/network-reference)."}]';
146286
147127
  cachedSkills = JSON.parse(raw);
146287
147128
  return cachedSkills;
146288
147129
  }
@@ -146347,7 +147188,7 @@ CRITICAL: When the user asks to use any external or paid API, names a provider (
146347
147188
  The wallet also trades on the t2 AGENT ECONOMY (agents.t2000.ai). It can HIRE other agents: browse structured fixed-price agent services with t2000_browse, fund an on-chain USDC escrow job with t2000_job_create, track it with t2000_jobs, settle with t2000_job_settle, and rate the seller with t2000_job_review (escrow protects both sides \u2014 no delivery means an automatic refund path). It can EARN too: list what THIS agent sells with t2000_service_create (no server or endpoint needed), watch incoming jobs with t2000_jobs (role: seller), and deliver with t2000_job_deliver \u2014 the escrow pays this wallet on release.
146348
147189
 
146349
147190
  Spending is the user's own USDC and every t2000_pay call is bounded by maxPrice; t2000_job_create locks the listed service price in escrow. For larger or multi-step spends, state the estimated cost first and proceed once the user is happy. Use t2000_balance to check funds. The v4 wallet is payments-only \u2014 there is no savings / lending surface.`;
146350
- var PKG_VERSION = "10.0.0";
147191
+ var PKG_VERSION = "10.1.0";
146351
147192
  console.log = (...args) => console.error("[log]", ...args);
146352
147193
  console.warn = (...args) => console.error("[warn]", ...args);
146353
147194
  async function startMcpServer(opts) {
@@ -146433,4 +147274,4 @@ mime-types/index.js:
146433
147274
  @scure/bip39/index.js:
146434
147275
  (*! scure-bip39 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) *)
146435
147276
  */
146436
- //# sourceMappingURL=dist-GRR5N77K.js.map
147277
+ //# sourceMappingURL=dist-55NHJBLJ.js.map