@t2000/cli 5.1.0 → 5.2.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-KVEHGTYJ.js} +266 -232
- package/dist/dist-KVEHGTYJ.js.map +1 -0
- package/dist/index.js +231 -331
- 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
|
-
}
|
|
28221
|
-
}
|
|
28222
|
-
assertNotLocked() {
|
|
28223
|
-
this.load();
|
|
28224
|
-
if (this.config.locked) {
|
|
28225
|
-
throw new SafeguardError("locked", {});
|
|
28226
|
-
}
|
|
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
|
+
});
|
|
28227
28296
|
}
|
|
28228
|
-
|
|
28229
|
-
|
|
28230
|
-
|
|
28231
|
-
|
|
28232
|
-
|
|
28233
|
-
|
|
28234
|
-
|
|
28235
|
-
|
|
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
|
-
}
|
|
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
|
+
});
|
|
28248
28305
|
}
|
|
28249
|
-
|
|
28250
|
-
|
|
28251
|
-
|
|
28252
|
-
this.
|
|
28306
|
+
}
|
|
28307
|
+
var LimitEnforcer = class {
|
|
28308
|
+
constructor(configDir) {
|
|
28309
|
+
this.configDir = configDir;
|
|
28253
28310
|
}
|
|
28254
|
-
|
|
28255
|
-
|
|
28256
|
-
|
|
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
|
+
});
|
|
28257
28320
|
}
|
|
28258
|
-
|
|
28259
|
-
|
|
28260
|
-
this.
|
|
28321
|
+
/** Add a settled write's USD value to today's cumulative total. */
|
|
28322
|
+
record(amountUsd) {
|
|
28323
|
+
recordDailySpend(amountUsd, this.configDir);
|
|
28261
28324
|
}
|
|
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();
|
|
28325
|
+
getLimits() {
|
|
28326
|
+
return getLimits(this.configDir);
|
|
28271
28327
|
}
|
|
28272
|
-
|
|
28273
|
-
this.
|
|
28274
|
-
this.resetDailyIfNewDay();
|
|
28275
|
-
return { ...this.config };
|
|
28328
|
+
hasLimits() {
|
|
28329
|
+
return hasLimits(this.configDir);
|
|
28276
28330
|
}
|
|
28277
|
-
|
|
28278
|
-
|
|
28331
|
+
setLimits(limits) {
|
|
28332
|
+
setLimits(limits, this.configDir);
|
|
28279
28333
|
}
|
|
28280
|
-
|
|
28281
|
-
|
|
28282
|
-
if (this.config.dailyResetDate !== today) {
|
|
28283
|
-
this.config.dailyUsed = 0;
|
|
28284
|
-
this.config.dailyResetDate = today;
|
|
28285
|
-
this.save();
|
|
28286
|
-
}
|
|
28334
|
+
clearLimits() {
|
|
28335
|
+
clearLimits(this.configDir);
|
|
28287
28336
|
}
|
|
28288
|
-
|
|
28289
|
-
|
|
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();
|
|
@@ -31387,127 +31424,6 @@ function registerHistory(program3) {
|
|
|
31387
31424
|
|
|
31388
31425
|
// src/commands/send.ts
|
|
31389
31426
|
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
31427
|
var ACCEPTED_ASSETS = ["USDC", "USDsui", "SUI"];
|
|
31512
31428
|
var ACCEPTED_ASSETS_LIST = ACCEPTED_ASSETS.join(", ");
|
|
31513
31429
|
function parseSendArgs(args) {
|
|
@@ -31563,10 +31479,6 @@ Examples:
|
|
|
31563
31479
|
).action(async (amount, args, opts) => {
|
|
31564
31480
|
try {
|
|
31565
31481
|
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
31482
|
const agent = await withAgent({ keyPath: opts.key });
|
|
31571
31483
|
const result = await agent.send({
|
|
31572
31484
|
to: recipient,
|
|
@@ -31574,7 +31486,8 @@ Examples:
|
|
|
31574
31486
|
// The CLI parser already narrowed asset to USDC / USDsui / SUI;
|
|
31575
31487
|
// the SDK accepts `SupportedAsset` and re-validates via
|
|
31576
31488
|
// `assertAllowedAsset('send', …)` at runtime.
|
|
31577
|
-
asset
|
|
31489
|
+
asset,
|
|
31490
|
+
force: opts.force
|
|
31578
31491
|
});
|
|
31579
31492
|
if (isJsonMode()) {
|
|
31580
31493
|
printJson({
|
|
@@ -31629,16 +31542,6 @@ Examples:
|
|
|
31629
31542
|
async (amountStr, from, to, opts) => {
|
|
31630
31543
|
try {
|
|
31631
31544
|
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
31545
|
const agent = await withAgent({ keyPath: opts.key });
|
|
31643
31546
|
if (opts.quote) {
|
|
31644
31547
|
const quote = await agent.swapQuote({
|
|
@@ -31665,7 +31568,8 @@ Examples:
|
|
|
31665
31568
|
from: parsed.from,
|
|
31666
31569
|
to: parsed.to,
|
|
31667
31570
|
amount: parsed.amount,
|
|
31668
|
-
slippage
|
|
31571
|
+
slippage,
|
|
31572
|
+
force: opts.force
|
|
31669
31573
|
});
|
|
31670
31574
|
if (isJsonMode()) {
|
|
31671
31575
|
printJson(result);
|
|
@@ -31718,7 +31622,6 @@ Examples:
|
|
|
31718
31622
|
if (Number.isNaN(maxPrice) || maxPrice <= 0) {
|
|
31719
31623
|
throw new Error(`Invalid --max-price: "${opts.maxPrice}". Must be a positive number.`);
|
|
31720
31624
|
}
|
|
31721
|
-
await assertWithinLimits({ operation: "pay", amountUsd: maxPrice, force: opts.force });
|
|
31722
31625
|
const agent = await withAgent({ keyPath: opts.key });
|
|
31723
31626
|
const startTime = Date.now();
|
|
31724
31627
|
const method = opts.data && opts.method === "GET" ? "POST" : opts.method;
|
|
@@ -31731,7 +31634,8 @@ Examples:
|
|
|
31731
31634
|
method,
|
|
31732
31635
|
headers: opts.header,
|
|
31733
31636
|
body: opts.data,
|
|
31734
|
-
maxPrice
|
|
31637
|
+
maxPrice,
|
|
31638
|
+
force: opts.force
|
|
31735
31639
|
});
|
|
31736
31640
|
const elapsed = Date.now() - startTime;
|
|
31737
31641
|
if (isJsonMode()) {
|
|
@@ -32071,9 +31975,8 @@ var import_picocolors10 = __toESM(require_picocolors(), 1);
|
|
|
32071
31975
|
function registerLimitShow(parent) {
|
|
32072
31976
|
parent.command("show").description("Show current spending limits").action(async (opts) => {
|
|
32073
31977
|
try {
|
|
32074
|
-
const
|
|
32075
|
-
const
|
|
32076
|
-
const hasAny = limits.perTxUsd !== void 0 || limits.dailySendUsd !== void 0;
|
|
31978
|
+
const limits = getLimits(opts.configDir) ?? {};
|
|
31979
|
+
const hasAny = limits.perTxUsd !== void 0 || limits.dailyUsd !== void 0;
|
|
32077
31980
|
if (isJsonMode()) {
|
|
32078
31981
|
printJson({
|
|
32079
31982
|
limits: hasAny ? limits : null,
|
|
@@ -32093,8 +31996,8 @@ function registerLimitShow(parent) {
|
|
|
32093
31996
|
if (limits.perTxUsd !== void 0) {
|
|
32094
31997
|
printKeyValue("Per-transaction", import_picocolors10.default.green(`$${limits.perTxUsd}`));
|
|
32095
31998
|
}
|
|
32096
|
-
if (limits.
|
|
32097
|
-
printKeyValue("Daily
|
|
31999
|
+
if (limits.dailyUsd !== void 0) {
|
|
32000
|
+
printKeyValue("Daily (cumulative)", import_picocolors10.default.green(`$${limits.dailyUsd}`));
|
|
32098
32001
|
}
|
|
32099
32002
|
printBlank();
|
|
32100
32003
|
printInfo("Use `--force` on `t2 send` / `t2 swap` / `t2 pay` to override per-call.");
|
|
@@ -32117,7 +32020,7 @@ function parseLimitSetArgs(opts) {
|
|
|
32117
32020
|
}
|
|
32118
32021
|
const limits = {};
|
|
32119
32022
|
if (perTx !== void 0) limits.perTxUsd = perTx;
|
|
32120
|
-
if (daily !== void 0) limits.
|
|
32023
|
+
if (daily !== void 0) limits.dailyUsd = daily;
|
|
32121
32024
|
return limits;
|
|
32122
32025
|
}
|
|
32123
32026
|
function parseUsdFlag(flag, raw) {
|
|
@@ -32128,31 +32031,30 @@ function parseUsdFlag(flag, raw) {
|
|
|
32128
32031
|
return value;
|
|
32129
32032
|
}
|
|
32130
32033
|
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
|
|
32034
|
+
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
32035
|
"after",
|
|
32133
32036
|
`
|
|
32134
32037
|
Examples:
|
|
32135
32038
|
$ t2 limit set --per-tx 50 Cap every write at $50
|
|
32136
|
-
$ t2 limit set --daily 100 Cap
|
|
32039
|
+
$ t2 limit set --daily 100 Cap total spend at $100/day (cumulative)
|
|
32137
32040
|
$ t2 limit set --per-tx 50 --daily 100 Set both
|
|
32138
32041
|
`
|
|
32139
32042
|
).action(async (opts) => {
|
|
32140
32043
|
try {
|
|
32141
32044
|
const limits = parseLimitSetArgs({ perTx: opts.perTx, daily: opts.daily });
|
|
32142
|
-
|
|
32143
|
-
const next =
|
|
32144
|
-
const filePath = await writeConfig(next, opts.configPath);
|
|
32045
|
+
setLimits(limits, opts.configDir);
|
|
32046
|
+
const next = getLimits(opts.configDir);
|
|
32145
32047
|
if (isJsonMode()) {
|
|
32146
|
-
printJson({ ok: true,
|
|
32048
|
+
printJson({ ok: true, limits: next });
|
|
32147
32049
|
return;
|
|
32148
32050
|
}
|
|
32149
32051
|
printBlank();
|
|
32150
32052
|
printSuccess("Spending limits updated.");
|
|
32151
|
-
if (next
|
|
32152
|
-
printKeyValue("Per-transaction", import_picocolors11.default.green(`$${next.
|
|
32053
|
+
if (next?.perTxUsd !== void 0) {
|
|
32054
|
+
printKeyValue("Per-transaction", import_picocolors11.default.green(`$${next.perTxUsd}`));
|
|
32153
32055
|
}
|
|
32154
|
-
if (next
|
|
32155
|
-
printKeyValue("Daily
|
|
32056
|
+
if (next?.dailyUsd !== void 0) {
|
|
32057
|
+
printKeyValue("Daily (cumulative)", import_picocolors11.default.green(`$${next.dailyUsd}`));
|
|
32156
32058
|
}
|
|
32157
32059
|
printBlank();
|
|
32158
32060
|
printInfo("Use `t2 limit show` to view; `t2 limit reset` to clear.");
|
|
@@ -32167,8 +32069,7 @@ Examples:
|
|
|
32167
32069
|
function registerLimitReset(parent) {
|
|
32168
32070
|
parent.command("reset").description("Clear all spending limits").action(async (opts) => {
|
|
32169
32071
|
try {
|
|
32170
|
-
|
|
32171
|
-
if (!hasLimits(current)) {
|
|
32072
|
+
if (!hasLimits(opts.configDir)) {
|
|
32172
32073
|
if (isJsonMode()) {
|
|
32173
32074
|
printJson({ ok: true, cleared: false, reason: "no limits were set" });
|
|
32174
32075
|
return;
|
|
@@ -32178,10 +32079,9 @@ function registerLimitReset(parent) {
|
|
|
32178
32079
|
printBlank();
|
|
32179
32080
|
return;
|
|
32180
32081
|
}
|
|
32181
|
-
|
|
32182
|
-
const filePath = await writeConfig(next, opts.configPath);
|
|
32082
|
+
clearLimits(opts.configDir);
|
|
32183
32083
|
if (isJsonMode()) {
|
|
32184
|
-
printJson({ ok: true, cleared: true
|
|
32084
|
+
printJson({ ok: true, cleared: true });
|
|
32185
32085
|
return;
|
|
32186
32086
|
}
|
|
32187
32087
|
printBlank();
|
|
@@ -32216,7 +32116,7 @@ function registerMcpStart(parent) {
|
|
|
32216
32116
|
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
32117
|
let mod2;
|
|
32218
32118
|
try {
|
|
32219
|
-
mod2 = await import("./dist-
|
|
32119
|
+
mod2 = await import("./dist-KVEHGTYJ.js");
|
|
32220
32120
|
} catch {
|
|
32221
32121
|
console.error("MCP server not installed. Run:\n npm install -g @t2000/mcp");
|
|
32222
32122
|
process.exit(1);
|
|
@@ -32226,9 +32126,9 @@ function registerMcpStart(parent) {
|
|
|
32226
32126
|
}
|
|
32227
32127
|
|
|
32228
32128
|
// src/commands/mcp/platforms.ts
|
|
32229
|
-
import { readFile as
|
|
32230
|
-
import { join as join3, dirname as
|
|
32231
|
-
import { homedir as
|
|
32129
|
+
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
32130
|
+
import { join as join3, dirname as dirname2 } from "path";
|
|
32131
|
+
import { homedir as homedir2 } from "os";
|
|
32232
32132
|
import { existsSync as existsSync2 } from "fs";
|
|
32233
32133
|
var MCP_SERVER_ENTRY = {
|
|
32234
32134
|
command: "t2000",
|
|
@@ -32236,7 +32136,7 @@ var MCP_SERVER_ENTRY = {
|
|
|
32236
32136
|
};
|
|
32237
32137
|
var MCP_SERVER_KEY = "t2000";
|
|
32238
32138
|
function getPlatformConfigs() {
|
|
32239
|
-
const home =
|
|
32139
|
+
const home = homedir2();
|
|
32240
32140
|
return [
|
|
32241
32141
|
{
|
|
32242
32142
|
name: "Claude Desktop",
|
|
@@ -32257,18 +32157,18 @@ function getPlatformConfigs() {
|
|
|
32257
32157
|
}
|
|
32258
32158
|
async function readJsonFile(path2) {
|
|
32259
32159
|
try {
|
|
32260
|
-
const content = await
|
|
32160
|
+
const content = await readFile2(path2, "utf-8");
|
|
32261
32161
|
return JSON.parse(content);
|
|
32262
32162
|
} catch {
|
|
32263
32163
|
return {};
|
|
32264
32164
|
}
|
|
32265
32165
|
}
|
|
32266
32166
|
async function writeJsonFile(path2, data) {
|
|
32267
|
-
const dir =
|
|
32167
|
+
const dir = dirname2(path2);
|
|
32268
32168
|
if (!existsSync2(dir)) {
|
|
32269
|
-
await
|
|
32169
|
+
await mkdir2(dir, { recursive: true });
|
|
32270
32170
|
}
|
|
32271
|
-
await
|
|
32171
|
+
await writeFile2(path2, JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
32272
32172
|
}
|
|
32273
32173
|
function withMcpEntry(config) {
|
|
32274
32174
|
return {
|
|
@@ -32393,7 +32293,7 @@ Subcommands:
|
|
|
32393
32293
|
// src/commands/skills/lib.ts
|
|
32394
32294
|
import { stat } from "fs/promises";
|
|
32395
32295
|
import { join as join4 } from "path";
|
|
32396
|
-
import { homedir as
|
|
32296
|
+
import { homedir as homedir3 } from "os";
|
|
32397
32297
|
var MANIFEST_URL = "https://t2000.ai/.well-known/agent-skills/index.json";
|
|
32398
32298
|
var SKILL_PREFIXES = ["t2000-", "mpp-"];
|
|
32399
32299
|
function isManagedSkillName(name) {
|
|
@@ -32401,7 +32301,7 @@ function isManagedSkillName(name) {
|
|
|
32401
32301
|
}
|
|
32402
32302
|
var SKILL_TARGETS = ["agents", "cursor", "claude-code"];
|
|
32403
32303
|
function resolveTargetDir(target, useGlobal, cwd = process.cwd()) {
|
|
32404
|
-
const root = useGlobal ?
|
|
32304
|
+
const root = useGlobal ? homedir3() : cwd;
|
|
32405
32305
|
switch (target) {
|
|
32406
32306
|
case "agents":
|
|
32407
32307
|
return join4(root, ".agents", "skills");
|
|
@@ -32489,7 +32389,7 @@ function registerSkillsList(parent) {
|
|
|
32489
32389
|
}
|
|
32490
32390
|
|
|
32491
32391
|
// src/commands/skills/install.ts
|
|
32492
|
-
import { writeFile as
|
|
32392
|
+
import { writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
|
|
32493
32393
|
import { join as join5 } from "path";
|
|
32494
32394
|
function registerSkillsInstall(parent) {
|
|
32495
32395
|
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 +32405,15 @@ function registerSkillsInstall(parent) {
|
|
|
32505
32405
|
);
|
|
32506
32406
|
}
|
|
32507
32407
|
const targetDir = resolveTargetDir(target, useGlobal);
|
|
32508
|
-
await
|
|
32408
|
+
await mkdir3(targetDir, { recursive: true });
|
|
32509
32409
|
const installed = [];
|
|
32510
32410
|
for (const s of toInstall) {
|
|
32511
32411
|
const raw = await fetchSkill(s.url);
|
|
32512
32412
|
const transformed = transformForTarget(raw, target, s.description);
|
|
32513
32413
|
const relPath = filenameForTarget(s.name, target);
|
|
32514
32414
|
const fullPath = join5(targetDir, relPath);
|
|
32515
|
-
await
|
|
32516
|
-
await
|
|
32415
|
+
await mkdir3(join5(fullPath, ".."), { recursive: true });
|
|
32416
|
+
await writeFile3(fullPath, transformed, "utf-8");
|
|
32517
32417
|
installed.push({ name: s.name, path: fullPath });
|
|
32518
32418
|
}
|
|
32519
32419
|
if (isJsonMode()) {
|