@t2000/cli 5.1.0 → 5.3.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.
- package/dist/{dist-3PYU4RZC.js → dist-U65BYMC5.js} +266 -232
- package/dist/dist-U65BYMC5.js.map +1 -0
- package/dist/index.js +244 -334
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/dist-3PYU4RZC.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -13676,7 +13676,7 @@ var require_lib2 = __commonJS({
|
|
|
13676
13676
|
return matches;
|
|
13677
13677
|
};
|
|
13678
13678
|
exports.analyse = analyse;
|
|
13679
|
-
var detectFile = (filepath, opts = {}) => new Promise((
|
|
13679
|
+
var detectFile = (filepath, opts = {}) => new Promise((resolve2, reject) => {
|
|
13680
13680
|
let fd;
|
|
13681
13681
|
const fs = (0, node_1.default)();
|
|
13682
13682
|
const handler = (err, buffer) => {
|
|
@@ -13686,7 +13686,7 @@ var require_lib2 = __commonJS({
|
|
|
13686
13686
|
if (err) {
|
|
13687
13687
|
reject(err);
|
|
13688
13688
|
} else if (buffer) {
|
|
13689
|
-
|
|
13689
|
+
resolve2((0, exports.detect)(buffer));
|
|
13690
13690
|
} else {
|
|
13691
13691
|
reject(new Error("No error and no buffer received"));
|
|
13692
13692
|
}
|
|
@@ -21930,10 +21930,10 @@ var require_browser = __commonJS({
|
|
|
21930
21930
|
text = canvas;
|
|
21931
21931
|
canvas = void 0;
|
|
21932
21932
|
}
|
|
21933
|
-
return new Promise(function(
|
|
21933
|
+
return new Promise(function(resolve2, reject) {
|
|
21934
21934
|
try {
|
|
21935
21935
|
const data = QRCode.create(text, opts);
|
|
21936
|
-
|
|
21936
|
+
resolve2(renderFunc(data, canvas, opts));
|
|
21937
21937
|
} catch (e) {
|
|
21938
21938
|
reject(e);
|
|
21939
21939
|
}
|
|
@@ -22015,11 +22015,11 @@ var require_server = __commonJS({
|
|
|
22015
22015
|
}
|
|
22016
22016
|
function render(renderFunc, text, params) {
|
|
22017
22017
|
if (!params.cb) {
|
|
22018
|
-
return new Promise(function(
|
|
22018
|
+
return new Promise(function(resolve2, reject) {
|
|
22019
22019
|
try {
|
|
22020
22020
|
const data = QRCode.create(text, params.opts);
|
|
22021
22021
|
return renderFunc(data, params.opts, function(err, data2) {
|
|
22022
|
-
return err ? reject(err) :
|
|
22022
|
+
return err ? reject(err) : resolve2(data2);
|
|
22023
22023
|
});
|
|
22024
22024
|
} catch (e) {
|
|
22025
22025
|
reject(e);
|
|
@@ -28159,164 +28159,194 @@ async function resolveSuinsViaRpc(rawName, ctx = {}) {
|
|
|
28159
28159
|
return body.result ?? null;
|
|
28160
28160
|
}
|
|
28161
28161
|
init_errors();
|
|
28162
|
-
var
|
|
28163
|
-
|
|
28164
|
-
|
|
28165
|
-
|
|
28166
|
-
|
|
28167
|
-
|
|
28168
|
-
}
|
|
28169
|
-
|
|
28170
|
-
|
|
28171
|
-
|
|
28172
|
-
|
|
28173
|
-
|
|
28174
|
-
|
|
28175
|
-
|
|
28176
|
-
|
|
28177
|
-
|
|
28178
|
-
|
|
28162
|
+
var DEFAULT_CONFIG_DIR = join2(homedir(), ".t2000");
|
|
28163
|
+
function resolveConfigPath(configDir) {
|
|
28164
|
+
return join2(configDir ?? DEFAULT_CONFIG_DIR, "config.json");
|
|
28165
|
+
}
|
|
28166
|
+
function todayUtc() {
|
|
28167
|
+
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
28168
|
+
}
|
|
28169
|
+
function readLimitsFile(configDir) {
|
|
28170
|
+
const path2 = resolveConfigPath(configDir);
|
|
28171
|
+
try {
|
|
28172
|
+
return sanitize(JSON.parse(readFileSync(path2, "utf-8")));
|
|
28173
|
+
} catch {
|
|
28174
|
+
return {};
|
|
28175
|
+
}
|
|
28176
|
+
}
|
|
28177
|
+
function writeLimitsFile(file, configDir) {
|
|
28178
|
+
const path2 = resolveConfigPath(configDir);
|
|
28179
|
+
let existing = {};
|
|
28180
|
+
try {
|
|
28181
|
+
existing = JSON.parse(readFileSync(path2, "utf-8"));
|
|
28182
|
+
} catch {
|
|
28183
|
+
existing = {};
|
|
28184
|
+
}
|
|
28185
|
+
for (const dead of ["maxPerTx", "maxDailySend", "dailyUsed", "dailyResetDate", "locked"]) {
|
|
28186
|
+
delete existing[dead];
|
|
28187
|
+
}
|
|
28188
|
+
const merged = { ...existing };
|
|
28189
|
+
if (file.limits && (file.limits.perTxUsd !== void 0 || file.limits.dailyUsd !== void 0)) {
|
|
28190
|
+
merged.limits = file.limits;
|
|
28191
|
+
} else {
|
|
28192
|
+
delete merged.limits;
|
|
28193
|
+
}
|
|
28194
|
+
if (file.dailySpend) merged.dailySpend = file.dailySpend;
|
|
28195
|
+
else delete merged.dailySpend;
|
|
28196
|
+
const dir = dirname(path2);
|
|
28197
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
28198
|
+
writeFileSync(path2, JSON.stringify(merged, null, 2) + "\n", { mode: 384 });
|
|
28199
|
+
return path2;
|
|
28200
|
+
}
|
|
28201
|
+
function getLimits(configDir) {
|
|
28202
|
+
return readLimitsFile(configDir).limits;
|
|
28203
|
+
}
|
|
28204
|
+
function hasLimits(configDir) {
|
|
28205
|
+
const l = readLimitsFile(configDir).limits;
|
|
28206
|
+
return !!l && (l.perTxUsd !== void 0 || l.dailyUsd !== void 0);
|
|
28207
|
+
}
|
|
28208
|
+
function setLimits(limits, configDir) {
|
|
28209
|
+
const file = readLimitsFile(configDir);
|
|
28210
|
+
const merged = { ...file.limits };
|
|
28211
|
+
if (limits.perTxUsd !== void 0) merged.perTxUsd = limits.perTxUsd;
|
|
28212
|
+
if (limits.dailyUsd !== void 0) merged.dailyUsd = limits.dailyUsd;
|
|
28213
|
+
return writeLimitsFile({ ...file, limits: merged }, configDir);
|
|
28214
|
+
}
|
|
28215
|
+
function clearLimits(configDir) {
|
|
28216
|
+
const file = readLimitsFile(configDir);
|
|
28217
|
+
return writeLimitsFile({ ...file, limits: void 0 }, configDir);
|
|
28218
|
+
}
|
|
28219
|
+
function dailySpentToday(configDir) {
|
|
28220
|
+
const { dailySpend } = readLimitsFile(configDir);
|
|
28221
|
+
if (!dailySpend || dailySpend.date !== todayUtc()) return 0;
|
|
28222
|
+
return dailySpend.usd;
|
|
28223
|
+
}
|
|
28224
|
+
function recordDailySpend(usd, configDir) {
|
|
28225
|
+
if (!Number.isFinite(usd) || usd <= 0) return;
|
|
28226
|
+
const file = readLimitsFile(configDir);
|
|
28227
|
+
const today = todayUtc();
|
|
28228
|
+
const prior = file.dailySpend && file.dailySpend.date === today ? file.dailySpend.usd : 0;
|
|
28229
|
+
writeLimitsFile({ ...file, dailySpend: { date: today, usd: prior + usd } }, configDir);
|
|
28230
|
+
}
|
|
28231
|
+
function sanitize(raw) {
|
|
28232
|
+
if (typeof raw !== "object" || raw === null) return {};
|
|
28233
|
+
const r = raw;
|
|
28234
|
+
const out = {};
|
|
28235
|
+
if (typeof r.limits === "object" && r.limits !== null) {
|
|
28236
|
+
const l = r.limits;
|
|
28237
|
+
const limits = {};
|
|
28238
|
+
if (typeof l.perTxUsd === "number" && l.perTxUsd > 0) limits.perTxUsd = l.perTxUsd;
|
|
28239
|
+
if (typeof l.dailyUsd === "number" && l.dailyUsd > 0) limits.dailyUsd = l.dailyUsd;
|
|
28240
|
+
else if (typeof l.dailySendUsd === "number" && l.dailySendUsd > 0) limits.dailyUsd = l.dailySendUsd;
|
|
28241
|
+
if (limits.perTxUsd !== void 0 || limits.dailyUsd !== void 0) out.limits = limits;
|
|
28242
|
+
}
|
|
28243
|
+
if (typeof r.dailySpend === "object" && r.dailySpend !== null) {
|
|
28244
|
+
const d = r.dailySpend;
|
|
28245
|
+
if (typeof d.date === "string" && typeof d.usd === "number" && d.usd >= 0) {
|
|
28246
|
+
out.dailySpend = { date: d.date, usd: d.usd };
|
|
28247
|
+
}
|
|
28248
|
+
}
|
|
28249
|
+
return out;
|
|
28250
|
+
}
|
|
28251
|
+
var LimitExceededError = class extends Error {
|
|
28252
|
+
code = "LIMIT_EXCEEDED";
|
|
28253
|
+
operation;
|
|
28254
|
+
limitKind;
|
|
28255
|
+
limit;
|
|
28256
|
+
attempted;
|
|
28257
|
+
constructor(params) {
|
|
28258
|
+
const label = params.limitKind === "perTxUsd" ? "per-transaction limit" : "daily spend limit";
|
|
28259
|
+
super(
|
|
28260
|
+
`Exceeds ${label} ($${params.limit}). Attempted $${params.attempted.toFixed(2)}. Use --force / force:true to override.`
|
|
28261
|
+
);
|
|
28262
|
+
this.name = "LimitExceededError";
|
|
28263
|
+
this.operation = params.operation;
|
|
28264
|
+
this.limitKind = params.limitKind;
|
|
28265
|
+
this.limit = params.limit;
|
|
28266
|
+
this.attempted = params.attempted;
|
|
28179
28267
|
}
|
|
28180
28268
|
toJSON() {
|
|
28181
28269
|
return {
|
|
28182
|
-
error:
|
|
28270
|
+
error: this.code,
|
|
28183
28271
|
message: this.message,
|
|
28184
|
-
|
|
28185
|
-
|
|
28272
|
+
operation: this.operation,
|
|
28273
|
+
limitKind: this.limitKind,
|
|
28274
|
+
limit: this.limit,
|
|
28275
|
+
attempted: this.attempted
|
|
28186
28276
|
};
|
|
28187
28277
|
}
|
|
28188
28278
|
};
|
|
28189
|
-
function
|
|
28190
|
-
|
|
28191
|
-
|
|
28192
|
-
|
|
28193
|
-
|
|
28194
|
-
|
|
28195
|
-
|
|
28196
|
-
|
|
28197
|
-
}
|
|
28198
|
-
|
|
28199
|
-
|
|
28200
|
-
|
|
28201
|
-
|
|
28202
|
-
|
|
28203
|
-
|
|
28204
|
-
|
|
28205
|
-
|
|
28206
|
-
load() {
|
|
28207
|
-
if (!this.configPath) return;
|
|
28208
|
-
try {
|
|
28209
|
-
const raw = JSON.parse(readFileSync(this.configPath, "utf-8"));
|
|
28210
|
-
this.config = {
|
|
28211
|
-
...DEFAULT_SAFEGUARD_CONFIG,
|
|
28212
|
-
locked: raw.locked ?? false,
|
|
28213
|
-
maxPerTx: raw.maxPerTx ?? 0,
|
|
28214
|
-
maxDailySend: raw.maxDailySend ?? 0,
|
|
28215
|
-
dailyUsed: raw.dailyUsed ?? 0,
|
|
28216
|
-
dailyResetDate: raw.dailyResetDate ?? ""
|
|
28217
|
-
};
|
|
28218
|
-
} catch {
|
|
28219
|
-
this.config = { ...DEFAULT_SAFEGUARD_CONFIG };
|
|
28220
|
-
}
|
|
28279
|
+
function approxUsdValue(asset, amount) {
|
|
28280
|
+
const symbol = asset.toUpperCase();
|
|
28281
|
+
if (symbol === "USDC" || symbol === "USDSUI") return amount;
|
|
28282
|
+
return null;
|
|
28283
|
+
}
|
|
28284
|
+
function assertLimitConfig(input) {
|
|
28285
|
+
if (input.force) return;
|
|
28286
|
+
if (!Number.isFinite(input.amountUsd) || input.amountUsd <= 0) return;
|
|
28287
|
+
const { limits } = input;
|
|
28288
|
+
if (!limits) return;
|
|
28289
|
+
if (limits.perTxUsd !== void 0 && input.amountUsd > limits.perTxUsd) {
|
|
28290
|
+
throw new LimitExceededError({
|
|
28291
|
+
operation: input.operation,
|
|
28292
|
+
limitKind: "perTxUsd",
|
|
28293
|
+
limit: limits.perTxUsd,
|
|
28294
|
+
attempted: input.amountUsd
|
|
28295
|
+
});
|
|
28221
28296
|
}
|
|
28222
|
-
|
|
28223
|
-
|
|
28224
|
-
|
|
28225
|
-
|
|
28226
|
-
|
|
28297
|
+
if (limits.dailyUsd !== void 0 && input.spentTodayUsd + input.amountUsd > limits.dailyUsd) {
|
|
28298
|
+
throw new LimitExceededError({
|
|
28299
|
+
operation: input.operation,
|
|
28300
|
+
limitKind: "dailyUsd",
|
|
28301
|
+
// The cap is total/day; report the cap (attempted is THIS write's USD).
|
|
28302
|
+
limit: limits.dailyUsd,
|
|
28303
|
+
attempted: input.spentTodayUsd + input.amountUsd
|
|
28304
|
+
});
|
|
28227
28305
|
}
|
|
28228
|
-
|
|
28229
|
-
|
|
28230
|
-
|
|
28231
|
-
|
|
28232
|
-
}
|
|
28233
|
-
const amount = metadata.amount ?? 0;
|
|
28234
|
-
if (this.config.maxPerTx > 0 && amount > this.config.maxPerTx) {
|
|
28235
|
-
throw new SafeguardError("maxPerTx", {
|
|
28236
|
-
attempted: amount,
|
|
28237
|
-
limit: this.config.maxPerTx
|
|
28238
|
-
});
|
|
28239
|
-
}
|
|
28240
|
-
this.resetDailyIfNewDay();
|
|
28241
|
-
if (this.config.maxDailySend > 0 && this.config.dailyUsed + amount > this.config.maxDailySend) {
|
|
28242
|
-
throw new SafeguardError("maxDailySend", {
|
|
28243
|
-
attempted: amount,
|
|
28244
|
-
limit: this.config.maxDailySend,
|
|
28245
|
-
current: this.config.dailyUsed
|
|
28246
|
-
});
|
|
28247
|
-
}
|
|
28306
|
+
}
|
|
28307
|
+
var LimitEnforcer = class {
|
|
28308
|
+
constructor(configDir) {
|
|
28309
|
+
this.configDir = configDir;
|
|
28248
28310
|
}
|
|
28249
|
-
|
|
28250
|
-
|
|
28251
|
-
|
|
28252
|
-
|
|
28311
|
+
/** Throws `LimitExceededError` when the write exceeds an opted-in cap. */
|
|
28312
|
+
assert(input) {
|
|
28313
|
+
assertLimitConfig({
|
|
28314
|
+
limits: getLimits(this.configDir),
|
|
28315
|
+
spentTodayUsd: dailySpentToday(this.configDir),
|
|
28316
|
+
operation: input.operation,
|
|
28317
|
+
amountUsd: input.amountUsd,
|
|
28318
|
+
force: input.force
|
|
28319
|
+
});
|
|
28253
28320
|
}
|
|
28254
|
-
|
|
28255
|
-
|
|
28256
|
-
this.
|
|
28321
|
+
/** Add a settled write's USD value to today's cumulative total. */
|
|
28322
|
+
record(amountUsd) {
|
|
28323
|
+
recordDailySpend(amountUsd, this.configDir);
|
|
28257
28324
|
}
|
|
28258
|
-
|
|
28259
|
-
this.
|
|
28260
|
-
this.save();
|
|
28325
|
+
getLimits() {
|
|
28326
|
+
return getLimits(this.configDir);
|
|
28261
28327
|
}
|
|
28262
|
-
|
|
28263
|
-
|
|
28264
|
-
this.config.locked = value;
|
|
28265
|
-
} else if (key === "maxPerTx" && typeof value === "number") {
|
|
28266
|
-
this.config.maxPerTx = value;
|
|
28267
|
-
} else if (key === "maxDailySend" && typeof value === "number") {
|
|
28268
|
-
this.config.maxDailySend = value;
|
|
28269
|
-
}
|
|
28270
|
-
this.save();
|
|
28328
|
+
hasLimits() {
|
|
28329
|
+
return hasLimits(this.configDir);
|
|
28271
28330
|
}
|
|
28272
|
-
|
|
28273
|
-
this.
|
|
28274
|
-
this.resetDailyIfNewDay();
|
|
28275
|
-
return { ...this.config };
|
|
28331
|
+
setLimits(limits) {
|
|
28332
|
+
setLimits(limits, this.configDir);
|
|
28276
28333
|
}
|
|
28277
|
-
|
|
28278
|
-
|
|
28334
|
+
clearLimits() {
|
|
28335
|
+
clearLimits(this.configDir);
|
|
28279
28336
|
}
|
|
28280
|
-
|
|
28281
|
-
|
|
28282
|
-
if (this.config.dailyResetDate !== today) {
|
|
28283
|
-
this.config.dailyUsed = 0;
|
|
28284
|
-
this.config.dailyResetDate = today;
|
|
28285
|
-
this.save();
|
|
28286
|
-
}
|
|
28287
|
-
}
|
|
28288
|
-
save() {
|
|
28289
|
-
if (!this.configPath) return;
|
|
28290
|
-
try {
|
|
28291
|
-
let existing = {};
|
|
28292
|
-
try {
|
|
28293
|
-
existing = JSON.parse(readFileSync(this.configPath, "utf-8"));
|
|
28294
|
-
} catch {
|
|
28295
|
-
}
|
|
28296
|
-
const merged = {
|
|
28297
|
-
...existing,
|
|
28298
|
-
locked: this.config.locked,
|
|
28299
|
-
maxPerTx: this.config.maxPerTx,
|
|
28300
|
-
maxDailySend: this.config.maxDailySend,
|
|
28301
|
-
dailyUsed: this.config.dailyUsed,
|
|
28302
|
-
dailyResetDate: this.config.dailyResetDate
|
|
28303
|
-
};
|
|
28304
|
-
const dir = this.configPath.replace(/[/\\][^/\\]+$/, "");
|
|
28305
|
-
if (!existsSync(dir)) {
|
|
28306
|
-
mkdirSync(dir, { recursive: true });
|
|
28307
|
-
}
|
|
28308
|
-
writeFileSync(this.configPath, JSON.stringify(merged, null, 2) + "\n");
|
|
28309
|
-
} catch {
|
|
28310
|
-
}
|
|
28337
|
+
dailySpentToday() {
|
|
28338
|
+
return dailySpentToday(this.configDir);
|
|
28311
28339
|
}
|
|
28312
28340
|
};
|
|
28313
|
-
var
|
|
28341
|
+
var DEFAULT_CONFIG_DIR2 = join2(homedir(), ".t2000");
|
|
28314
28342
|
var T2000 = class _T2000 extends import_index2.default {
|
|
28315
28343
|
_signer;
|
|
28316
28344
|
_keypair;
|
|
28317
28345
|
client;
|
|
28318
28346
|
_address;
|
|
28319
|
-
|
|
28347
|
+
/** Unified spending-limit gate (per-tx + cumulative daily, USD). Shared by
|
|
28348
|
+
* CLI + MCP + programmatic writes — one gate, no bypass (R-0 Finding 1). */
|
|
28349
|
+
limits;
|
|
28320
28350
|
constructor(keypairOrSigner, client, configDir, isSignerMode) {
|
|
28321
28351
|
super();
|
|
28322
28352
|
if (isSignerMode) {
|
|
@@ -28330,8 +28360,7 @@ var T2000 = class _T2000 extends import_index2.default {
|
|
|
28330
28360
|
this._address = getAddress(kp);
|
|
28331
28361
|
}
|
|
28332
28362
|
this.client = client;
|
|
28333
|
-
this.
|
|
28334
|
-
this.enforcer.load();
|
|
28363
|
+
this.limits = new LimitEnforcer(configDir);
|
|
28335
28364
|
}
|
|
28336
28365
|
static async create(options = {}) {
|
|
28337
28366
|
const { keyPath, rpcUrl } = options;
|
|
@@ -28344,7 +28373,7 @@ var T2000 = class _T2000 extends import_index2.default {
|
|
|
28344
28373
|
);
|
|
28345
28374
|
}
|
|
28346
28375
|
const keypair = await loadKey(void 0, keyPath);
|
|
28347
|
-
return new _T2000(keypair, client,
|
|
28376
|
+
return new _T2000(keypair, client, DEFAULT_CONFIG_DIR2);
|
|
28348
28377
|
}
|
|
28349
28378
|
static fromPrivateKey(privateKey, options = {}) {
|
|
28350
28379
|
const keypair = keypairFromPrivateKey(privateKey);
|
|
@@ -28355,7 +28384,7 @@ var T2000 = class _T2000 extends import_index2.default {
|
|
|
28355
28384
|
const keypair = generateKeypair();
|
|
28356
28385
|
await saveKey(keypair, void 0, options.keyPath);
|
|
28357
28386
|
const client = getSuiClient();
|
|
28358
|
-
const agent = new _T2000(keypair, client,
|
|
28387
|
+
const agent = new _T2000(keypair, client, DEFAULT_CONFIG_DIR2);
|
|
28359
28388
|
const address = agent.address();
|
|
28360
28389
|
return { agent, address };
|
|
28361
28390
|
}
|
|
@@ -28377,11 +28406,10 @@ var T2000 = class _T2000 extends import_index2.default {
|
|
|
28377
28406
|
}
|
|
28378
28407
|
// -- MPP Payments --
|
|
28379
28408
|
async pay(options) {
|
|
28380
|
-
this.
|
|
28381
|
-
this.enforcer.check({ operation: "pay", amount: options.maxPrice ?? 1 });
|
|
28409
|
+
this.limits.assert({ operation: "pay", amountUsd: options.maxPrice ?? 0, force: options.force });
|
|
28382
28410
|
const result = await payWithMpp({ signer: this._signer, client: this.client, options });
|
|
28383
28411
|
if (result.paid) {
|
|
28384
|
-
this.
|
|
28412
|
+
this.limits.record(result.cost ?? options.maxPrice ?? 0);
|
|
28385
28413
|
}
|
|
28386
28414
|
return result;
|
|
28387
28415
|
}
|
|
@@ -28395,7 +28423,11 @@ var T2000 = class _T2000 extends import_index2.default {
|
|
|
28395
28423
|
// and the S.323 build-tracker entry.
|
|
28396
28424
|
// -- Swap --
|
|
28397
28425
|
async swap(params) {
|
|
28398
|
-
this.
|
|
28426
|
+
this.limits.assert({
|
|
28427
|
+
operation: "swap",
|
|
28428
|
+
amountUsd: approxUsdValue(params.from, params.amount) ?? 0,
|
|
28429
|
+
force: params.force
|
|
28430
|
+
});
|
|
28399
28431
|
const { findSwapRoute: findSwapRoute2, buildSwapTx: buildSwapTx2, resolveTokenType: resolveTokenType2 } = await Promise.resolve().then(() => (init_cetus_swap(), cetus_swap_exports));
|
|
28400
28432
|
const fromType = resolveTokenType2(params.from);
|
|
28401
28433
|
const toType = resolveTokenType2(params.to);
|
|
@@ -28487,6 +28519,7 @@ var T2000 = class _T2000 extends import_index2.default {
|
|
|
28487
28519
|
const fromName = resolveSymbol(fromType);
|
|
28488
28520
|
const toName = resolveSymbol(toType);
|
|
28489
28521
|
const routeDesc = route.routerData.paths?.map((p) => p.provider).filter(Boolean).slice(0, 3).join(" + ") ?? "Cetus Aggregator";
|
|
28522
|
+
this.limits.record(approxUsdValue(params.from, params.amount) ?? 0);
|
|
28490
28523
|
return {
|
|
28491
28524
|
success: true,
|
|
28492
28525
|
tx: gasResult.digest,
|
|
@@ -28543,7 +28576,6 @@ var T2000 = class _T2000 extends import_index2.default {
|
|
|
28543
28576
|
* the "build via gRPC, execute via JSON-RPC" hybrid).
|
|
28544
28577
|
*/
|
|
28545
28578
|
async send(params) {
|
|
28546
|
-
this.enforcer.assertNotLocked();
|
|
28547
28579
|
const asset = params.asset;
|
|
28548
28580
|
if (!asset) {
|
|
28549
28581
|
throw new T2000Error(
|
|
@@ -28553,6 +28585,11 @@ var T2000 = class _T2000 extends import_index2.default {
|
|
|
28553
28585
|
}
|
|
28554
28586
|
assertAllowedAsset("send", asset);
|
|
28555
28587
|
const sendableAsset = asset;
|
|
28588
|
+
this.limits.assert({
|
|
28589
|
+
operation: "send",
|
|
28590
|
+
amountUsd: approxUsdValue(sendableAsset, params.amount) ?? 0,
|
|
28591
|
+
force: params.force
|
|
28592
|
+
});
|
|
28556
28593
|
const resolved = await this.resolveRecipient(params.to);
|
|
28557
28594
|
const sendAmount = params.amount;
|
|
28558
28595
|
const sendTo = resolved.address;
|
|
@@ -28564,7 +28601,7 @@ var T2000 = class _T2000 extends import_index2.default {
|
|
|
28564
28601
|
() => buildSendTx({ client: this.client, address: this._address, to: sendTo, amount: sendAmount, asset: sendableAsset }),
|
|
28565
28602
|
{ buildClient }
|
|
28566
28603
|
);
|
|
28567
|
-
this.
|
|
28604
|
+
this.limits.record(approxUsdValue(sendableAsset, sendAmount) ?? 0);
|
|
28568
28605
|
const balance = await this.balance();
|
|
28569
28606
|
this.emitBalanceChange(sendableAsset, sendAmount, "send", gasResult.digest);
|
|
28570
28607
|
return {
|
|
@@ -29753,13 +29790,13 @@ var PromisePolyfill = class extends Promise {
|
|
|
29753
29790
|
// Available starting from Node 22
|
|
29754
29791
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers
|
|
29755
29792
|
static withResolver() {
|
|
29756
|
-
let
|
|
29793
|
+
let resolve2;
|
|
29757
29794
|
let reject;
|
|
29758
29795
|
const promise = new Promise((res, rej) => {
|
|
29759
|
-
|
|
29796
|
+
resolve2 = res;
|
|
29760
29797
|
reject = rej;
|
|
29761
29798
|
});
|
|
29762
|
-
return { promise, resolve:
|
|
29799
|
+
return { promise, resolve: resolve2, reject };
|
|
29763
29800
|
}
|
|
29764
29801
|
};
|
|
29765
29802
|
|
|
@@ -29793,7 +29830,7 @@ function createPrompt(view) {
|
|
|
29793
29830
|
output
|
|
29794
29831
|
});
|
|
29795
29832
|
const screen = new ScreenManager(rl);
|
|
29796
|
-
const { promise, resolve:
|
|
29833
|
+
const { promise, resolve: resolve2, reject } = PromisePolyfill.withResolver();
|
|
29797
29834
|
const cancel = () => reject(new CancelPromptError());
|
|
29798
29835
|
if (signal) {
|
|
29799
29836
|
const abort = () => reject(new AbortPromptError({ cause: signal.reason }));
|
|
@@ -29820,7 +29857,7 @@ function createPrompt(view) {
|
|
|
29820
29857
|
cycle(() => {
|
|
29821
29858
|
try {
|
|
29822
29859
|
const nextView = view(config, (value) => {
|
|
29823
|
-
setImmediate(() =>
|
|
29860
|
+
setImmediate(() => resolve2(value));
|
|
29824
29861
|
});
|
|
29825
29862
|
if (nextView === void 0) {
|
|
29826
29863
|
const callerFilename = callSites[1]?.getFileName();
|
|
@@ -31132,7 +31169,9 @@ async function askHidden(message) {
|
|
|
31132
31169
|
}
|
|
31133
31170
|
|
|
31134
31171
|
// src/commands/init.ts
|
|
31135
|
-
var
|
|
31172
|
+
var DEFAULT_PER_TX_USD = 25;
|
|
31173
|
+
var DEFAULT_DAILY_USD = 100;
|
|
31174
|
+
var limitsFooter = (perTx, daily) => `Spending limits ON: $${perTx}/tx, $${daily}/day (cumulative). Change with \`t2 limit set\`, or override a single call with --force.`;
|
|
31136
31175
|
function registerInit(program3) {
|
|
31137
31176
|
program3.command("init").description("Create a new Agent Wallet (no PIN; plain Bech32 key file with 0o600 perms)").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option(
|
|
31138
31177
|
"--import [secret]",
|
|
@@ -31159,8 +31198,16 @@ function registerInit(program3) {
|
|
|
31159
31198
|
await saveKey(keypair, void 0, opts.key);
|
|
31160
31199
|
address = getAddress(keypair);
|
|
31161
31200
|
}
|
|
31201
|
+
if (!hasLimits()) {
|
|
31202
|
+
setLimits({ perTxUsd: DEFAULT_PER_TX_USD, dailyUsd: DEFAULT_DAILY_USD });
|
|
31203
|
+
}
|
|
31162
31204
|
if (isJsonMode()) {
|
|
31163
|
-
printJson({
|
|
31205
|
+
printJson({
|
|
31206
|
+
address,
|
|
31207
|
+
imported,
|
|
31208
|
+
configPath: opts.key ?? "~/.t2000/wallet.key",
|
|
31209
|
+
limits: { perTxUsd: DEFAULT_PER_TX_USD, dailyUsd: DEFAULT_DAILY_USD }
|
|
31210
|
+
});
|
|
31164
31211
|
return;
|
|
31165
31212
|
}
|
|
31166
31213
|
printBlank();
|
|
@@ -31168,7 +31215,7 @@ function registerInit(program3) {
|
|
|
31168
31215
|
printKeyValue("Address", address);
|
|
31169
31216
|
printKeyValue("Path", opts.key ?? "~/.t2000/wallet.key");
|
|
31170
31217
|
printBlank();
|
|
31171
|
-
printLine(`\u26A0 ${
|
|
31218
|
+
printLine(`\u26A0 ${limitsFooter(DEFAULT_PER_TX_USD, DEFAULT_DAILY_USD)}`);
|
|
31172
31219
|
printBlank();
|
|
31173
31220
|
try {
|
|
31174
31221
|
await T2000.create({ keyPath: opts.key });
|
|
@@ -31387,127 +31434,6 @@ function registerHistory(program3) {
|
|
|
31387
31434
|
|
|
31388
31435
|
// src/commands/send.ts
|
|
31389
31436
|
var import_picocolors5 = __toESM(require_picocolors(), 1);
|
|
31390
|
-
|
|
31391
|
-
// src/lib/config-store.ts
|
|
31392
|
-
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2, access as access2 } from "fs/promises";
|
|
31393
|
-
import { dirname as dirname2, resolve as resolve2 } from "path";
|
|
31394
|
-
import { homedir as homedir2 } from "os";
|
|
31395
|
-
var DEFAULT_CONFIG_PATH = "~/.t2000/config.json";
|
|
31396
|
-
function expandPath2(p) {
|
|
31397
|
-
if (p.startsWith("~")) return resolve2(homedir2(), p.slice(2));
|
|
31398
|
-
return resolve2(p);
|
|
31399
|
-
}
|
|
31400
|
-
async function readConfig(configPath) {
|
|
31401
|
-
const filePath = expandPath2(configPath ?? DEFAULT_CONFIG_PATH);
|
|
31402
|
-
try {
|
|
31403
|
-
const content = await readFile2(filePath, "utf-8");
|
|
31404
|
-
const parsed = JSON.parse(content);
|
|
31405
|
-
return sanitizeConfig(parsed);
|
|
31406
|
-
} catch {
|
|
31407
|
-
return {};
|
|
31408
|
-
}
|
|
31409
|
-
}
|
|
31410
|
-
async function writeConfig(config, configPath) {
|
|
31411
|
-
const filePath = expandPath2(configPath ?? DEFAULT_CONFIG_PATH);
|
|
31412
|
-
await mkdir2(dirname2(filePath), { recursive: true });
|
|
31413
|
-
const sanitized = sanitizeConfig(config);
|
|
31414
|
-
await writeFile2(filePath, JSON.stringify(sanitized, null, 2), { mode: 384 });
|
|
31415
|
-
return filePath;
|
|
31416
|
-
}
|
|
31417
|
-
function setLimits(config, limits) {
|
|
31418
|
-
const merged = { ...config.limits };
|
|
31419
|
-
if (limits.perTxUsd !== void 0) merged.perTxUsd = limits.perTxUsd;
|
|
31420
|
-
if (limits.dailySendUsd !== void 0) merged.dailySendUsd = limits.dailySendUsd;
|
|
31421
|
-
return { ...config, limits: merged };
|
|
31422
|
-
}
|
|
31423
|
-
function clearLimits(config) {
|
|
31424
|
-
const { limits: _, ...rest } = config;
|
|
31425
|
-
return rest;
|
|
31426
|
-
}
|
|
31427
|
-
function hasLimits(config) {
|
|
31428
|
-
return config.limits !== void 0 && (config.limits.perTxUsd !== void 0 || config.limits.dailySendUsd !== void 0);
|
|
31429
|
-
}
|
|
31430
|
-
function sanitizeConfig(raw) {
|
|
31431
|
-
if (typeof raw !== "object" || raw === null) return {};
|
|
31432
|
-
const r = raw;
|
|
31433
|
-
const out = {};
|
|
31434
|
-
if (typeof r.limits === "object" && r.limits !== null) {
|
|
31435
|
-
const l = r.limits;
|
|
31436
|
-
const limits = {};
|
|
31437
|
-
if (typeof l.perTxUsd === "number" && l.perTxUsd > 0) limits.perTxUsd = l.perTxUsd;
|
|
31438
|
-
if (typeof l.dailySendUsd === "number" && l.dailySendUsd > 0) limits.dailySendUsd = l.dailySendUsd;
|
|
31439
|
-
if (limits.perTxUsd !== void 0 || limits.dailySendUsd !== void 0) out.limits = limits;
|
|
31440
|
-
}
|
|
31441
|
-
return out;
|
|
31442
|
-
}
|
|
31443
|
-
|
|
31444
|
-
// src/commands/limit/enforce.ts
|
|
31445
|
-
var LimitExceededError = class extends Error {
|
|
31446
|
-
code = "LIMIT_EXCEEDED";
|
|
31447
|
-
limit;
|
|
31448
|
-
limitKind;
|
|
31449
|
-
attempted;
|
|
31450
|
-
operation;
|
|
31451
|
-
constructor(params) {
|
|
31452
|
-
const label = params.limitKind === "perTxUsd" ? "per-transaction limit" : "daily limit";
|
|
31453
|
-
super(
|
|
31454
|
-
`Exceeds ${label} ($${params.limit}). Attempted $${params.attempted.toFixed(2)}. Use --force to override.`
|
|
31455
|
-
);
|
|
31456
|
-
this.name = "LimitExceededError";
|
|
31457
|
-
this.operation = params.operation;
|
|
31458
|
-
this.limitKind = params.limitKind;
|
|
31459
|
-
this.limit = params.limit;
|
|
31460
|
-
this.attempted = params.attempted;
|
|
31461
|
-
}
|
|
31462
|
-
toJSON() {
|
|
31463
|
-
return {
|
|
31464
|
-
error: this.code,
|
|
31465
|
-
message: this.message,
|
|
31466
|
-
operation: this.operation,
|
|
31467
|
-
limitKind: this.limitKind,
|
|
31468
|
-
limit: this.limit,
|
|
31469
|
-
attempted: this.attempted
|
|
31470
|
-
};
|
|
31471
|
-
}
|
|
31472
|
-
};
|
|
31473
|
-
function assertLimitConfig(input) {
|
|
31474
|
-
if (input.force) return;
|
|
31475
|
-
if (!Number.isFinite(input.amountUsd) || input.amountUsd <= 0) return;
|
|
31476
|
-
const limits = input.config.limits;
|
|
31477
|
-
if (!limits) return;
|
|
31478
|
-
if (limits.perTxUsd !== void 0 && input.amountUsd > limits.perTxUsd) {
|
|
31479
|
-
throw new LimitExceededError({
|
|
31480
|
-
operation: input.operation,
|
|
31481
|
-
limitKind: "perTxUsd",
|
|
31482
|
-
limit: limits.perTxUsd,
|
|
31483
|
-
attempted: input.amountUsd
|
|
31484
|
-
});
|
|
31485
|
-
}
|
|
31486
|
-
if (input.operation === "send" && limits.dailySendUsd !== void 0 && input.amountUsd > limits.dailySendUsd) {
|
|
31487
|
-
throw new LimitExceededError({
|
|
31488
|
-
operation: input.operation,
|
|
31489
|
-
limitKind: "dailySendUsd",
|
|
31490
|
-
limit: limits.dailySendUsd,
|
|
31491
|
-
attempted: input.amountUsd
|
|
31492
|
-
});
|
|
31493
|
-
}
|
|
31494
|
-
}
|
|
31495
|
-
async function assertWithinLimits(input) {
|
|
31496
|
-
const config = await readConfig(input.configPath);
|
|
31497
|
-
assertLimitConfig({
|
|
31498
|
-
config,
|
|
31499
|
-
operation: input.operation,
|
|
31500
|
-
amountUsd: input.amountUsd,
|
|
31501
|
-
force: input.force
|
|
31502
|
-
});
|
|
31503
|
-
}
|
|
31504
|
-
function approxUsdValue(asset, amount) {
|
|
31505
|
-
const symbol = asset.toUpperCase();
|
|
31506
|
-
if (symbol === "USDC" || symbol === "USDSUI") return amount;
|
|
31507
|
-
return null;
|
|
31508
|
-
}
|
|
31509
|
-
|
|
31510
|
-
// src/commands/send.ts
|
|
31511
31437
|
var ACCEPTED_ASSETS = ["USDC", "USDsui", "SUI"];
|
|
31512
31438
|
var ACCEPTED_ASSETS_LIST = ACCEPTED_ASSETS.join(", ");
|
|
31513
31439
|
function parseSendArgs(args) {
|
|
@@ -31563,10 +31489,6 @@ Examples:
|
|
|
31563
31489
|
).action(async (amount, args, opts) => {
|
|
31564
31490
|
try {
|
|
31565
31491
|
const { amount: parsedAmount, asset, recipient } = parseSendArgs([amount, ...args]);
|
|
31566
|
-
const usdValue = approxUsdValue(asset, parsedAmount);
|
|
31567
|
-
if (usdValue !== null) {
|
|
31568
|
-
await assertWithinLimits({ operation: "send", amountUsd: usdValue, force: opts.force });
|
|
31569
|
-
}
|
|
31570
31492
|
const agent = await withAgent({ keyPath: opts.key });
|
|
31571
31493
|
const result = await agent.send({
|
|
31572
31494
|
to: recipient,
|
|
@@ -31574,7 +31496,8 @@ Examples:
|
|
|
31574
31496
|
// The CLI parser already narrowed asset to USDC / USDsui / SUI;
|
|
31575
31497
|
// the SDK accepts `SupportedAsset` and re-validates via
|
|
31576
31498
|
// `assertAllowedAsset('send', …)` at runtime.
|
|
31577
|
-
asset
|
|
31499
|
+
asset,
|
|
31500
|
+
force: opts.force
|
|
31578
31501
|
});
|
|
31579
31502
|
if (isJsonMode()) {
|
|
31580
31503
|
printJson({
|
|
@@ -31629,16 +31552,6 @@ Examples:
|
|
|
31629
31552
|
async (amountStr, from, to, opts) => {
|
|
31630
31553
|
try {
|
|
31631
31554
|
const parsed = parseSwapArgs(amountStr, from, to);
|
|
31632
|
-
if (!opts.quote) {
|
|
31633
|
-
const usdValue = approxUsdValue(parsed.from, parsed.amount);
|
|
31634
|
-
if (usdValue !== null) {
|
|
31635
|
-
await assertWithinLimits({
|
|
31636
|
-
operation: "swap",
|
|
31637
|
-
amountUsd: usdValue,
|
|
31638
|
-
force: opts.force
|
|
31639
|
-
});
|
|
31640
|
-
}
|
|
31641
|
-
}
|
|
31642
31555
|
const agent = await withAgent({ keyPath: opts.key });
|
|
31643
31556
|
if (opts.quote) {
|
|
31644
31557
|
const quote = await agent.swapQuote({
|
|
@@ -31665,7 +31578,8 @@ Examples:
|
|
|
31665
31578
|
from: parsed.from,
|
|
31666
31579
|
to: parsed.to,
|
|
31667
31580
|
amount: parsed.amount,
|
|
31668
|
-
slippage
|
|
31581
|
+
slippage,
|
|
31582
|
+
force: opts.force
|
|
31669
31583
|
});
|
|
31670
31584
|
if (isJsonMode()) {
|
|
31671
31585
|
printJson(result);
|
|
@@ -31718,7 +31632,6 @@ Examples:
|
|
|
31718
31632
|
if (Number.isNaN(maxPrice) || maxPrice <= 0) {
|
|
31719
31633
|
throw new Error(`Invalid --max-price: "${opts.maxPrice}". Must be a positive number.`);
|
|
31720
31634
|
}
|
|
31721
|
-
await assertWithinLimits({ operation: "pay", amountUsd: maxPrice, force: opts.force });
|
|
31722
31635
|
const agent = await withAgent({ keyPath: opts.key });
|
|
31723
31636
|
const startTime = Date.now();
|
|
31724
31637
|
const method = opts.data && opts.method === "GET" ? "POST" : opts.method;
|
|
@@ -31731,7 +31644,8 @@ Examples:
|
|
|
31731
31644
|
method,
|
|
31732
31645
|
headers: opts.header,
|
|
31733
31646
|
body: opts.data,
|
|
31734
|
-
maxPrice
|
|
31647
|
+
maxPrice,
|
|
31648
|
+
force: opts.force
|
|
31735
31649
|
});
|
|
31736
31650
|
const elapsed = Date.now() - startTime;
|
|
31737
31651
|
if (isJsonMode()) {
|
|
@@ -32071,9 +31985,8 @@ var import_picocolors10 = __toESM(require_picocolors(), 1);
|
|
|
32071
31985
|
function registerLimitShow(parent) {
|
|
32072
31986
|
parent.command("show").description("Show current spending limits").action(async (opts) => {
|
|
32073
31987
|
try {
|
|
32074
|
-
const
|
|
32075
|
-
const
|
|
32076
|
-
const hasAny = limits.perTxUsd !== void 0 || limits.dailySendUsd !== void 0;
|
|
31988
|
+
const limits = getLimits(opts.configDir) ?? {};
|
|
31989
|
+
const hasAny = limits.perTxUsd !== void 0 || limits.dailyUsd !== void 0;
|
|
32077
31990
|
if (isJsonMode()) {
|
|
32078
31991
|
printJson({
|
|
32079
31992
|
limits: hasAny ? limits : null,
|
|
@@ -32093,8 +32006,8 @@ function registerLimitShow(parent) {
|
|
|
32093
32006
|
if (limits.perTxUsd !== void 0) {
|
|
32094
32007
|
printKeyValue("Per-transaction", import_picocolors10.default.green(`$${limits.perTxUsd}`));
|
|
32095
32008
|
}
|
|
32096
|
-
if (limits.
|
|
32097
|
-
printKeyValue("Daily
|
|
32009
|
+
if (limits.dailyUsd !== void 0) {
|
|
32010
|
+
printKeyValue("Daily (cumulative)", import_picocolors10.default.green(`$${limits.dailyUsd}`));
|
|
32098
32011
|
}
|
|
32099
32012
|
printBlank();
|
|
32100
32013
|
printInfo("Use `--force` on `t2 send` / `t2 swap` / `t2 pay` to override per-call.");
|
|
@@ -32117,7 +32030,7 @@ function parseLimitSetArgs(opts) {
|
|
|
32117
32030
|
}
|
|
32118
32031
|
const limits = {};
|
|
32119
32032
|
if (perTx !== void 0) limits.perTxUsd = perTx;
|
|
32120
|
-
if (daily !== void 0) limits.
|
|
32033
|
+
if (daily !== void 0) limits.dailyUsd = daily;
|
|
32121
32034
|
return limits;
|
|
32122
32035
|
}
|
|
32123
32036
|
function parseUsdFlag(flag, raw) {
|
|
@@ -32128,31 +32041,30 @@ function parseUsdFlag(flag, raw) {
|
|
|
32128
32041
|
return value;
|
|
32129
32042
|
}
|
|
32130
32043
|
function registerLimitSet(parent) {
|
|
32131
|
-
parent.command("set").description("Set spending limits (opt-in; either flag is optional)").option("--per-tx <usd>", "Max USD per single transaction (send | swap | pay)").option("--daily <usd>", "Max USD per
|
|
32044
|
+
parent.command("set").description("Set spending limits (opt-in; either flag is optional)").option("--per-tx <usd>", "Max USD per single transaction (send | swap | pay)").option("--daily <usd>", "Max CUMULATIVE USD spend per day across all writes").addHelpText(
|
|
32132
32045
|
"after",
|
|
32133
32046
|
`
|
|
32134
32047
|
Examples:
|
|
32135
32048
|
$ t2 limit set --per-tx 50 Cap every write at $50
|
|
32136
|
-
$ t2 limit set --daily 100 Cap
|
|
32049
|
+
$ t2 limit set --daily 100 Cap total spend at $100/day (cumulative)
|
|
32137
32050
|
$ t2 limit set --per-tx 50 --daily 100 Set both
|
|
32138
32051
|
`
|
|
32139
32052
|
).action(async (opts) => {
|
|
32140
32053
|
try {
|
|
32141
32054
|
const limits = parseLimitSetArgs({ perTx: opts.perTx, daily: opts.daily });
|
|
32142
|
-
|
|
32143
|
-
const next =
|
|
32144
|
-
const filePath = await writeConfig(next, opts.configPath);
|
|
32055
|
+
setLimits(limits, opts.configDir);
|
|
32056
|
+
const next = getLimits(opts.configDir);
|
|
32145
32057
|
if (isJsonMode()) {
|
|
32146
|
-
printJson({ ok: true,
|
|
32058
|
+
printJson({ ok: true, limits: next });
|
|
32147
32059
|
return;
|
|
32148
32060
|
}
|
|
32149
32061
|
printBlank();
|
|
32150
32062
|
printSuccess("Spending limits updated.");
|
|
32151
|
-
if (next
|
|
32152
|
-
printKeyValue("Per-transaction", import_picocolors11.default.green(`$${next.
|
|
32063
|
+
if (next?.perTxUsd !== void 0) {
|
|
32064
|
+
printKeyValue("Per-transaction", import_picocolors11.default.green(`$${next.perTxUsd}`));
|
|
32153
32065
|
}
|
|
32154
|
-
if (next
|
|
32155
|
-
printKeyValue("Daily
|
|
32066
|
+
if (next?.dailyUsd !== void 0) {
|
|
32067
|
+
printKeyValue("Daily (cumulative)", import_picocolors11.default.green(`$${next.dailyUsd}`));
|
|
32156
32068
|
}
|
|
32157
32069
|
printBlank();
|
|
32158
32070
|
printInfo("Use `t2 limit show` to view; `t2 limit reset` to clear.");
|
|
@@ -32167,8 +32079,7 @@ Examples:
|
|
|
32167
32079
|
function registerLimitReset(parent) {
|
|
32168
32080
|
parent.command("reset").description("Clear all spending limits").action(async (opts) => {
|
|
32169
32081
|
try {
|
|
32170
|
-
|
|
32171
|
-
if (!hasLimits(current)) {
|
|
32082
|
+
if (!hasLimits(opts.configDir)) {
|
|
32172
32083
|
if (isJsonMode()) {
|
|
32173
32084
|
printJson({ ok: true, cleared: false, reason: "no limits were set" });
|
|
32174
32085
|
return;
|
|
@@ -32178,10 +32089,9 @@ function registerLimitReset(parent) {
|
|
|
32178
32089
|
printBlank();
|
|
32179
32090
|
return;
|
|
32180
32091
|
}
|
|
32181
|
-
|
|
32182
|
-
const filePath = await writeConfig(next, opts.configPath);
|
|
32092
|
+
clearLimits(opts.configDir);
|
|
32183
32093
|
if (isJsonMode()) {
|
|
32184
|
-
printJson({ ok: true, cleared: true
|
|
32094
|
+
printJson({ ok: true, cleared: true });
|
|
32185
32095
|
return;
|
|
32186
32096
|
}
|
|
32187
32097
|
printBlank();
|
|
@@ -32216,7 +32126,7 @@ function registerMcpStart(parent) {
|
|
|
32216
32126
|
parent.command("start", { isDefault: true }).description("Start MCP server (stdio transport \u2014 for AI client integration)").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(async (opts) => {
|
|
32217
32127
|
let mod2;
|
|
32218
32128
|
try {
|
|
32219
|
-
mod2 = await import("./dist-
|
|
32129
|
+
mod2 = await import("./dist-U65BYMC5.js");
|
|
32220
32130
|
} catch {
|
|
32221
32131
|
console.error("MCP server not installed. Run:\n npm install -g @t2000/mcp");
|
|
32222
32132
|
process.exit(1);
|
|
@@ -32226,9 +32136,9 @@ function registerMcpStart(parent) {
|
|
|
32226
32136
|
}
|
|
32227
32137
|
|
|
32228
32138
|
// src/commands/mcp/platforms.ts
|
|
32229
|
-
import { readFile as
|
|
32230
|
-
import { join as join3, dirname as
|
|
32231
|
-
import { homedir as
|
|
32139
|
+
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
32140
|
+
import { join as join3, dirname as dirname2 } from "path";
|
|
32141
|
+
import { homedir as homedir2 } from "os";
|
|
32232
32142
|
import { existsSync as existsSync2 } from "fs";
|
|
32233
32143
|
var MCP_SERVER_ENTRY = {
|
|
32234
32144
|
command: "t2000",
|
|
@@ -32236,7 +32146,7 @@ var MCP_SERVER_ENTRY = {
|
|
|
32236
32146
|
};
|
|
32237
32147
|
var MCP_SERVER_KEY = "t2000";
|
|
32238
32148
|
function getPlatformConfigs() {
|
|
32239
|
-
const home =
|
|
32149
|
+
const home = homedir2();
|
|
32240
32150
|
return [
|
|
32241
32151
|
{
|
|
32242
32152
|
name: "Claude Desktop",
|
|
@@ -32257,18 +32167,18 @@ function getPlatformConfigs() {
|
|
|
32257
32167
|
}
|
|
32258
32168
|
async function readJsonFile(path2) {
|
|
32259
32169
|
try {
|
|
32260
|
-
const content = await
|
|
32170
|
+
const content = await readFile2(path2, "utf-8");
|
|
32261
32171
|
return JSON.parse(content);
|
|
32262
32172
|
} catch {
|
|
32263
32173
|
return {};
|
|
32264
32174
|
}
|
|
32265
32175
|
}
|
|
32266
32176
|
async function writeJsonFile(path2, data) {
|
|
32267
|
-
const dir =
|
|
32177
|
+
const dir = dirname2(path2);
|
|
32268
32178
|
if (!existsSync2(dir)) {
|
|
32269
|
-
await
|
|
32179
|
+
await mkdir2(dir, { recursive: true });
|
|
32270
32180
|
}
|
|
32271
|
-
await
|
|
32181
|
+
await writeFile2(path2, JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
32272
32182
|
}
|
|
32273
32183
|
function withMcpEntry(config) {
|
|
32274
32184
|
return {
|
|
@@ -32393,7 +32303,7 @@ Subcommands:
|
|
|
32393
32303
|
// src/commands/skills/lib.ts
|
|
32394
32304
|
import { stat } from "fs/promises";
|
|
32395
32305
|
import { join as join4 } from "path";
|
|
32396
|
-
import { homedir as
|
|
32306
|
+
import { homedir as homedir3 } from "os";
|
|
32397
32307
|
var MANIFEST_URL = "https://t2000.ai/.well-known/agent-skills/index.json";
|
|
32398
32308
|
var SKILL_PREFIXES = ["t2000-", "mpp-"];
|
|
32399
32309
|
function isManagedSkillName(name) {
|
|
@@ -32401,7 +32311,7 @@ function isManagedSkillName(name) {
|
|
|
32401
32311
|
}
|
|
32402
32312
|
var SKILL_TARGETS = ["agents", "cursor", "claude-code"];
|
|
32403
32313
|
function resolveTargetDir(target, useGlobal, cwd = process.cwd()) {
|
|
32404
|
-
const root = useGlobal ?
|
|
32314
|
+
const root = useGlobal ? homedir3() : cwd;
|
|
32405
32315
|
switch (target) {
|
|
32406
32316
|
case "agents":
|
|
32407
32317
|
return join4(root, ".agents", "skills");
|
|
@@ -32489,7 +32399,7 @@ function registerSkillsList(parent) {
|
|
|
32489
32399
|
}
|
|
32490
32400
|
|
|
32491
32401
|
// src/commands/skills/install.ts
|
|
32492
|
-
import { writeFile as
|
|
32402
|
+
import { writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
|
|
32493
32403
|
import { join as join5 } from "path";
|
|
32494
32404
|
function registerSkillsInstall(parent) {
|
|
32495
32405
|
parent.command("install [slug]").description("Install all skills (or one named slug) into a local directory").option("--target <name>", "Target client layout: agents (default), cursor, claude-code", "agents").option("--global", "Install to ~/.<target>/ instead of <cwd>/.<target>/").action(async (slug, opts) => {
|
|
@@ -32505,15 +32415,15 @@ function registerSkillsInstall(parent) {
|
|
|
32505
32415
|
);
|
|
32506
32416
|
}
|
|
32507
32417
|
const targetDir = resolveTargetDir(target, useGlobal);
|
|
32508
|
-
await
|
|
32418
|
+
await mkdir3(targetDir, { recursive: true });
|
|
32509
32419
|
const installed = [];
|
|
32510
32420
|
for (const s of toInstall) {
|
|
32511
32421
|
const raw = await fetchSkill(s.url);
|
|
32512
32422
|
const transformed = transformForTarget(raw, target, s.description);
|
|
32513
32423
|
const relPath = filenameForTarget(s.name, target);
|
|
32514
32424
|
const fullPath = join5(targetDir, relPath);
|
|
32515
|
-
await
|
|
32516
|
-
await
|
|
32425
|
+
await mkdir3(join5(fullPath, ".."), { recursive: true });
|
|
32426
|
+
await writeFile3(fullPath, transformed, "utf-8");
|
|
32517
32427
|
installed.push({ name: s.name, path: fullPath });
|
|
32518
32428
|
}
|
|
32519
32429
|
if (isJsonMode()) {
|