@t2000/cli 3.1.1 → 3.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/README.md +12 -7
- package/dist/{chunk-R7KXQRHQ.js → chunk-YSV3YXTK.js} +101 -326
- package/dist/chunk-YSV3YXTK.js.map +1 -0
- package/dist/{dist-A7D5R6SM.js → dist-7RF5QOXU.js} +4 -20
- package/dist/{dist-2LJUAYXZ.js → dist-UDLQ4IJN.js} +113 -280
- package/dist/{dist-2LJUAYXZ.js.map → dist-UDLQ4IJN.js.map} +1 -1
- package/dist/index.js +266 -104
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/dist/chunk-R7KXQRHQ.js.map +0 -1
- /package/dist/{dist-A7D5R6SM.js.map → dist-7RF5QOXU.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
saveKey,
|
|
13
13
|
truncateAddress,
|
|
14
14
|
walletExists
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-YSV3YXTK.js";
|
|
16
16
|
import {
|
|
17
17
|
esm_default3 as esm_default,
|
|
18
18
|
esm_default8 as esm_default2
|
|
@@ -3613,13 +3613,13 @@ async function installMcpForPlatforms(platforms) {
|
|
|
3613
3613
|
}
|
|
3614
3614
|
}
|
|
3615
3615
|
function registerInit(program3) {
|
|
3616
|
-
program3.command("init").description("Create a new
|
|
3616
|
+
program3.command("init").description("Create a new Agentic Wallet \u2014 guided setup with MCP + safeguards").option("--key <path>", "Key file path").action(async (opts) => {
|
|
3617
3617
|
try {
|
|
3618
3618
|
const { checkbox, input, password } = await import("./esm-G2QBGTGV.js");
|
|
3619
3619
|
console.log("");
|
|
3620
3620
|
console.log(` \u250C\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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510`);
|
|
3621
3621
|
console.log(` \u2502 ${import_picocolors2.default.bold("Welcome to t2000")} \u2502`);
|
|
3622
|
-
console.log(` \u2502
|
|
3622
|
+
console.log(` \u2502 Agentic Wallet for AI agents \u2502`);
|
|
3623
3623
|
console.log(` \u2514\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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518`);
|
|
3624
3624
|
console.log("");
|
|
3625
3625
|
const hasWallet = await walletExists(opts.key);
|
|
@@ -3655,7 +3655,7 @@ function registerInit(program3) {
|
|
|
3655
3655
|
` ${import_picocolors2.default.green("\u2713")} Checking ${import_picocolors2.default.green("\u2713")} Savings ${import_picocolors2.default.green("\u2713")} Credit`
|
|
3656
3656
|
);
|
|
3657
3657
|
printBlank();
|
|
3658
|
-
printLine(` \u{1F389} ${import_picocolors2.default.green("
|
|
3658
|
+
printLine(` \u{1F389} ${import_picocolors2.default.green("Agentic Wallet created")}`);
|
|
3659
3659
|
printLine(` Address: ${import_picocolors2.default.yellow(address.slice(0, 6) + "..." + address.slice(-4))}`);
|
|
3660
3660
|
printBlank();
|
|
3661
3661
|
printInfo("Fund your wallet to start:");
|
|
@@ -3875,23 +3875,28 @@ function registerAddress(program3) {
|
|
|
3875
3875
|
});
|
|
3876
3876
|
}
|
|
3877
3877
|
|
|
3878
|
-
// src/commands/
|
|
3879
|
-
function
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
return;
|
|
3888
|
-
}
|
|
3889
|
-
printHeader("Fund your wallet");
|
|
3890
|
-
console.log(info.instructions);
|
|
3891
|
-
printBlank();
|
|
3892
|
-
} catch (error) {
|
|
3893
|
-
handleError(error);
|
|
3878
|
+
// src/commands/fund.ts
|
|
3879
|
+
async function runFund(opts) {
|
|
3880
|
+
try {
|
|
3881
|
+
const pin = await resolvePin();
|
|
3882
|
+
const agent = await T2000.create({ pin, keyPath: opts.key });
|
|
3883
|
+
const info = await agent.fund();
|
|
3884
|
+
if (isJsonMode()) {
|
|
3885
|
+
printJson(info);
|
|
3886
|
+
return;
|
|
3894
3887
|
}
|
|
3888
|
+
printHeader("Fund your Agentic Wallet");
|
|
3889
|
+
console.log(info.instructions);
|
|
3890
|
+
printBlank();
|
|
3891
|
+
} catch (error) {
|
|
3892
|
+
handleError(error);
|
|
3893
|
+
}
|
|
3894
|
+
}
|
|
3895
|
+
function registerFund(program3) {
|
|
3896
|
+
program3.command("fund").description("Show how to fund your Agentic Wallet (receive address + supported networks)").option("--key <path>", "Key file path").action(runFund);
|
|
3897
|
+
program3.command("deposit").description("[deprecated] Use `t2000 fund` instead").option("--key <path>", "Key file path").action(async (opts) => {
|
|
3898
|
+
console.error("Warning: `t2000 deposit` is deprecated. Use `t2000 fund` instead.");
|
|
3899
|
+
await runFund(opts);
|
|
3895
3900
|
});
|
|
3896
3901
|
}
|
|
3897
3902
|
|
|
@@ -4139,27 +4144,36 @@ function registerSave(program3) {
|
|
|
4139
4144
|
}
|
|
4140
4145
|
};
|
|
4141
4146
|
program3.command("save").description("Deposit USDC or USDsui into NAVI lending to earn yield").argument("<amount>", 'Amount of the chosen asset to save (or "all")').option("--key <path>", "Key file path").option("--protocol <name>", "Protocol to use (e.g. navi)").option("--asset <symbol>", "Asset to save: USDC (default) or USDsui").action(action);
|
|
4142
|
-
program3.command("supply").description("Deposit USDC or USDsui into NAVI lending (alias for save)").argument("<amount>", 'Amount of the chosen asset to save (or "all")').option("--key <path>", "Key file path").option("--protocol <name>", "Protocol to use (e.g. navi)").option("--asset <symbol>", "Asset to save: USDC (default) or USDsui").action(action);
|
|
4143
4147
|
}
|
|
4144
4148
|
|
|
4145
4149
|
// src/commands/withdraw.ts
|
|
4150
|
+
var WITHDRAW_ASSETS = ["USDC", "USDsui"];
|
|
4151
|
+
function resolveWithdrawAsset(input) {
|
|
4152
|
+
if (!input) return void 0;
|
|
4153
|
+
const match2 = WITHDRAW_ASSETS.find((a) => a.toLowerCase() === input.toLowerCase());
|
|
4154
|
+
if (!match2) {
|
|
4155
|
+
throw new Error(`--asset must be one of: ${WITHDRAW_ASSETS.join(", ")}. Got: "${input}"`);
|
|
4156
|
+
}
|
|
4157
|
+
return match2;
|
|
4158
|
+
}
|
|
4146
4159
|
function registerWithdraw(program3) {
|
|
4147
|
-
program3.command("withdraw").description("Withdraw USDC or USDsui from NAVI lending").argument("<amount>", 'Amount to withdraw (or "all")').option("--key <path>", "Key file path").option("--protocol <name>", "Protocol to use (e.g. navi)").option("--asset <
|
|
4160
|
+
program3.command("withdraw").description("Withdraw USDC or USDsui from NAVI lending").argument("<amount>", 'Amount to withdraw (or "all")').option("--key <path>", "Key file path").option("--protocol <name>", "Protocol to use (e.g. navi)").option("--asset <symbol>", "Asset to withdraw: USDC or USDsui (omit to auto-detect)").action(async (amountStr, opts) => {
|
|
4148
4161
|
try {
|
|
4149
4162
|
const amount = amountStr === "all" ? "all" : parseFloat(amountStr);
|
|
4150
4163
|
if (amount !== "all" && (isNaN(amount) || amount <= 0)) {
|
|
4151
4164
|
throw new Error('Amount must be a positive number or "all"');
|
|
4152
4165
|
}
|
|
4166
|
+
const asset = resolveWithdrawAsset(opts.asset);
|
|
4153
4167
|
const pin = await resolvePin();
|
|
4154
4168
|
const agent = await T2000.create({ pin, keyPath: opts.key });
|
|
4155
|
-
const result = await agent.withdraw({ amount, asset
|
|
4169
|
+
const result = await agent.withdraw({ amount, asset, protocol: opts.protocol });
|
|
4156
4170
|
if (isJsonMode()) {
|
|
4157
4171
|
printJson(result);
|
|
4158
4172
|
return;
|
|
4159
4173
|
}
|
|
4160
|
-
const
|
|
4174
|
+
const withdrawnAsset = result.asset ?? asset ?? "USDC";
|
|
4161
4175
|
printBlank();
|
|
4162
|
-
printSuccess(`Withdrew ${formatUsd(result.amount)} ${
|
|
4176
|
+
printSuccess(`Withdrew ${formatUsd(result.amount)} ${withdrawnAsset}`);
|
|
4163
4177
|
printKeyValue("Tx", explorerUrl(result.tx));
|
|
4164
4178
|
printBlank();
|
|
4165
4179
|
} catch (error) {
|
|
@@ -7877,7 +7891,7 @@ function registerLock(program3) {
|
|
|
7877
7891
|
});
|
|
7878
7892
|
program3.command("unlock").description("Unlock agent \u2014 resume operations").action(async () => {
|
|
7879
7893
|
try {
|
|
7880
|
-
const { T2000: T20003 } = await import("./dist-
|
|
7894
|
+
const { T2000: T20003 } = await import("./dist-7RF5QOXU.js");
|
|
7881
7895
|
const MAX_ATTEMPTS2 = 3;
|
|
7882
7896
|
let pin;
|
|
7883
7897
|
for (let attempt = 1; attempt <= MAX_ATTEMPTS2; attempt++) {
|
|
@@ -8051,7 +8065,7 @@ function registerMcp(program3) {
|
|
|
8051
8065
|
mcp.command("start", { isDefault: true }).description("Start MCP server (stdio transport)").option("--key <path>", "Key file path").action(async (opts) => {
|
|
8052
8066
|
let mod;
|
|
8053
8067
|
try {
|
|
8054
|
-
mod = await import("./dist-
|
|
8068
|
+
mod = await import("./dist-UDLQ4IJN.js");
|
|
8055
8069
|
} catch {
|
|
8056
8070
|
console.error(
|
|
8057
8071
|
"MCP server not installed. Run:\n npm install -g @t2000/mcp"
|
|
@@ -8243,17 +8257,24 @@ function registerClaimRewards(program3) {
|
|
|
8243
8257
|
|
|
8244
8258
|
// src/commands/swap.ts
|
|
8245
8259
|
var import_picocolors13 = __toESM(require_picocolors(), 1);
|
|
8260
|
+
function parseSwapArgs(amountStr, from, toKeywordOrTo, to) {
|
|
8261
|
+
const amount = parseFloat(amountStr);
|
|
8262
|
+
if (isNaN(amount) || amount <= 0) {
|
|
8263
|
+
throw new Error("Amount must be a positive number");
|
|
8264
|
+
}
|
|
8265
|
+
if (toKeywordOrTo?.toLowerCase() === "for" && !to) {
|
|
8266
|
+
throw new Error("Usage: t2000 swap <amount> <from> [for] <to>");
|
|
8267
|
+
}
|
|
8268
|
+
const actualTo = to ?? toKeywordOrTo;
|
|
8269
|
+
if (!actualTo) {
|
|
8270
|
+
throw new Error("Usage: t2000 swap <amount> <from> [for] <to>");
|
|
8271
|
+
}
|
|
8272
|
+
return { amount, from, to: actualTo };
|
|
8273
|
+
}
|
|
8246
8274
|
function registerSwap(program3) {
|
|
8247
8275
|
program3.command("swap").description("Swap tokens via Cetus Aggregator (20+ DEXs)").argument("<amount>", "Amount to swap").argument("<from>", "Source token (e.g. SUI, USDC, CETUS)").argument("[to_keyword]", '"for" keyword (optional)').argument("<to>", "Target token (e.g. USDC, SUI, DEEP)").option("--slippage <pct>", "Max slippage percentage (default: 1)", "1").option("--key <path>", "Key file path").action(async (amountStr, from, toKeywordOrTo, to, opts) => {
|
|
8248
8276
|
try {
|
|
8249
|
-
const amount =
|
|
8250
|
-
if (isNaN(amount) || amount <= 0) {
|
|
8251
|
-
throw new Error("Amount must be a positive number");
|
|
8252
|
-
}
|
|
8253
|
-
if (toKeywordOrTo?.toLowerCase() === "for" && !to) {
|
|
8254
|
-
throw new Error("Usage: t2000 swap <amount> <from> [for] <to>");
|
|
8255
|
-
}
|
|
8256
|
-
const actualTo = to ?? toKeywordOrTo;
|
|
8277
|
+
const { amount, to: actualTo } = parseSwapArgs(amountStr, from, toKeywordOrTo, to);
|
|
8257
8278
|
const slippage = Math.min(parseFloat(opts.slippage ?? "1") / 100, 0.05);
|
|
8258
8279
|
const pin = await resolvePin();
|
|
8259
8280
|
const agent = await T2000.create({ pin, keyPath: opts.key });
|
|
@@ -8311,64 +8332,8 @@ function registerSwapQuote(program3) {
|
|
|
8311
8332
|
});
|
|
8312
8333
|
}
|
|
8313
8334
|
|
|
8314
|
-
// src/commands/stake.ts
|
|
8315
|
-
var import_picocolors15 = __toESM(require_picocolors(), 1);
|
|
8316
|
-
function registerStake(program3) {
|
|
8317
|
-
program3.command("stake").description("Stake SUI for vSUI via VOLO liquid staking (earn ~3-5% APY)").argument("<amount>", "Amount of SUI to stake (minimum 1)").option("--key <path>", "Key file path").action(async (amountStr, opts) => {
|
|
8318
|
-
try {
|
|
8319
|
-
const amount = parseFloat(amountStr);
|
|
8320
|
-
if (isNaN(amount) || amount < 1) {
|
|
8321
|
-
throw new Error("Amount must be at least 1 SUI");
|
|
8322
|
-
}
|
|
8323
|
-
const pin = await resolvePin();
|
|
8324
|
-
const agent = await T2000.create({ pin, keyPath: opts.key });
|
|
8325
|
-
const result = await agent.stakeVSui({ amount });
|
|
8326
|
-
if (isJsonMode()) {
|
|
8327
|
-
printJson(result);
|
|
8328
|
-
return;
|
|
8329
|
-
}
|
|
8330
|
-
printBlank();
|
|
8331
|
-
printSuccess(`Staked ${import_picocolors15.default.yellow(String(result.amountSui))} SUI for ${import_picocolors15.default.green(result.vSuiReceived.toFixed(4))} vSUI`);
|
|
8332
|
-
printSuccess(`APY: ${import_picocolors15.default.green(`${(result.apy * 100).toFixed(2)}%`)}`);
|
|
8333
|
-
printKeyValue("Gas", `${result.gasCost.toFixed(4)} SUI`);
|
|
8334
|
-
printKeyValue("Tx", explorerUrl(result.tx));
|
|
8335
|
-
printBlank();
|
|
8336
|
-
} catch (error) {
|
|
8337
|
-
handleError(error);
|
|
8338
|
-
}
|
|
8339
|
-
});
|
|
8340
|
-
}
|
|
8341
|
-
|
|
8342
|
-
// src/commands/unstake.ts
|
|
8343
|
-
var import_picocolors16 = __toESM(require_picocolors(), 1);
|
|
8344
|
-
function registerUnstake(program3) {
|
|
8345
|
-
program3.command("unstake").description("Unstake vSUI back to SUI (returns SUI including accumulated yield)").argument("<amount>", 'Amount of vSUI to unstake (or "all")').option("--key <path>", "Key file path").action(async (amountStr, opts) => {
|
|
8346
|
-
try {
|
|
8347
|
-
const amount = amountStr === "all" ? "all" : parseFloat(amountStr);
|
|
8348
|
-
if (amount !== "all" && (isNaN(amount) || amount <= 0)) {
|
|
8349
|
-
throw new Error('Amount must be a positive number or "all"');
|
|
8350
|
-
}
|
|
8351
|
-
const pin = await resolvePin();
|
|
8352
|
-
const agent = await T2000.create({ pin, keyPath: opts.key });
|
|
8353
|
-
const result = await agent.unstakeVSui({ amount });
|
|
8354
|
-
if (isJsonMode()) {
|
|
8355
|
-
printJson(result);
|
|
8356
|
-
return;
|
|
8357
|
-
}
|
|
8358
|
-
printBlank();
|
|
8359
|
-
printSuccess(`Unstaked ${import_picocolors16.default.yellow(result.vSuiAmount.toFixed(4))} vSUI`);
|
|
8360
|
-
printSuccess(`Received ${import_picocolors16.default.green(result.suiReceived.toFixed(4))} SUI`);
|
|
8361
|
-
printKeyValue("Gas", `${result.gasCost.toFixed(4)} SUI`);
|
|
8362
|
-
printKeyValue("Tx", explorerUrl(result.tx));
|
|
8363
|
-
printBlank();
|
|
8364
|
-
} catch (error) {
|
|
8365
|
-
handleError(error);
|
|
8366
|
-
}
|
|
8367
|
-
});
|
|
8368
|
-
}
|
|
8369
|
-
|
|
8370
8335
|
// src/commands/receive.ts
|
|
8371
|
-
var
|
|
8336
|
+
var import_picocolors15 = __toESM(require_picocolors(), 1);
|
|
8372
8337
|
function registerReceive(program3) {
|
|
8373
8338
|
program3.command("receive").description("Generate a payment request with address and QR code").option("--amount <number>", "Amount to request").option("--currency <symbol>", "Currency (default: USDC)", "USDC").option("--memo <text>", "Payment note").option("--label <text>", "Description for the request").option("--key <path>", "Key file path").action(async (opts) => {
|
|
8374
8339
|
try {
|
|
@@ -8390,13 +8355,13 @@ function registerReceive(program3) {
|
|
|
8390
8355
|
}
|
|
8391
8356
|
printHeader("Payment Request");
|
|
8392
8357
|
if (request.label) {
|
|
8393
|
-
printLine(
|
|
8358
|
+
printLine(import_picocolors15.default.bold(request.label));
|
|
8394
8359
|
printBlank();
|
|
8395
8360
|
}
|
|
8396
8361
|
if (request.amount != null) {
|
|
8397
|
-
printLine(
|
|
8362
|
+
printLine(import_picocolors15.default.bold(` $${request.amount.toFixed(2)} ${request.currency}`));
|
|
8398
8363
|
} else {
|
|
8399
|
-
printLine(
|
|
8364
|
+
printLine(import_picocolors15.default.dim(" Any amount") + ` ${request.currency}`);
|
|
8400
8365
|
}
|
|
8401
8366
|
printBlank();
|
|
8402
8367
|
printDivider();
|
|
@@ -8410,7 +8375,7 @@ function registerReceive(program3) {
|
|
|
8410
8375
|
printBlank();
|
|
8411
8376
|
printKeyValue("Payment URI", request.qrUri);
|
|
8412
8377
|
printBlank();
|
|
8413
|
-
printLine(
|
|
8378
|
+
printLine(import_picocolors15.default.dim("Share this URI or scan the QR to pay via any Sui wallet."));
|
|
8414
8379
|
printBlank();
|
|
8415
8380
|
} catch (error) {
|
|
8416
8381
|
handleError(error);
|
|
@@ -8418,28 +8383,226 @@ function registerReceive(program3) {
|
|
|
8418
8383
|
});
|
|
8419
8384
|
}
|
|
8420
8385
|
|
|
8386
|
+
// src/commands/skills.ts
|
|
8387
|
+
import { writeFile as writeFile5, mkdir as mkdir5, readdir, unlink as unlink2, rmdir, stat } from "fs/promises";
|
|
8388
|
+
import { join as join8 } from "path";
|
|
8389
|
+
import { homedir as homedir9 } from "os";
|
|
8390
|
+
var MANIFEST_URL = "https://t2000.ai/.well-known/agent-skills/index.json";
|
|
8391
|
+
var SKILL_PREFIXES = ["t2000-", "mpp-"];
|
|
8392
|
+
function isManagedSkillName(name) {
|
|
8393
|
+
return SKILL_PREFIXES.some((prefix) => name.startsWith(prefix));
|
|
8394
|
+
}
|
|
8395
|
+
var SKILL_TARGETS = ["agents", "cursor", "claude-code"];
|
|
8396
|
+
function resolveTargetDir(target, useGlobal, cwd = process.cwd()) {
|
|
8397
|
+
const root = useGlobal ? homedir9() : cwd;
|
|
8398
|
+
switch (target) {
|
|
8399
|
+
case "agents":
|
|
8400
|
+
return join8(root, ".agents", "skills");
|
|
8401
|
+
case "cursor":
|
|
8402
|
+
return join8(root, ".cursor", "rules");
|
|
8403
|
+
case "claude-code":
|
|
8404
|
+
return join8(root, ".claude", "skills");
|
|
8405
|
+
}
|
|
8406
|
+
}
|
|
8407
|
+
function filenameForTarget(slug, target) {
|
|
8408
|
+
switch (target) {
|
|
8409
|
+
case "agents":
|
|
8410
|
+
case "claude-code":
|
|
8411
|
+
return join8(slug, "SKILL.md");
|
|
8412
|
+
case "cursor":
|
|
8413
|
+
return `${slug}.mdc`;
|
|
8414
|
+
}
|
|
8415
|
+
}
|
|
8416
|
+
function transformForTarget(content, target, description) {
|
|
8417
|
+
if (target !== "cursor") return content;
|
|
8418
|
+
const stripped = content.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n*/, "");
|
|
8419
|
+
const safeDescription = JSON.stringify(description);
|
|
8420
|
+
return `---
|
|
8421
|
+
description: ${safeDescription}
|
|
8422
|
+
alwaysApply: false
|
|
8423
|
+
---
|
|
8424
|
+
${stripped}`;
|
|
8425
|
+
}
|
|
8426
|
+
function resolveSkillTarget(input) {
|
|
8427
|
+
const value = input ?? "agents";
|
|
8428
|
+
const match2 = SKILL_TARGETS.find((t) => t === value);
|
|
8429
|
+
if (!match2) {
|
|
8430
|
+
throw new Error(`--target must be one of: ${SKILL_TARGETS.join(", ")}. Got: "${value}"`);
|
|
8431
|
+
}
|
|
8432
|
+
return match2;
|
|
8433
|
+
}
|
|
8434
|
+
async function fetchManifest() {
|
|
8435
|
+
const res = await fetch(MANIFEST_URL);
|
|
8436
|
+
if (!res.ok) {
|
|
8437
|
+
throw new Error(
|
|
8438
|
+
`Failed to fetch skills manifest from ${MANIFEST_URL} (${res.status} ${res.statusText}). Check your network or fall back to \`git clone https://github.com/mission69b/t2000\` for offline install.`
|
|
8439
|
+
);
|
|
8440
|
+
}
|
|
8441
|
+
return await res.json();
|
|
8442
|
+
}
|
|
8443
|
+
async function fetchSkill(url) {
|
|
8444
|
+
const res = await fetch(url);
|
|
8445
|
+
if (!res.ok) {
|
|
8446
|
+
throw new Error(`Failed to fetch skill ${url} (${res.status} ${res.statusText})`);
|
|
8447
|
+
}
|
|
8448
|
+
return await res.text();
|
|
8449
|
+
}
|
|
8450
|
+
async function dirExists(path) {
|
|
8451
|
+
try {
|
|
8452
|
+
const s = await stat(path);
|
|
8453
|
+
return s.isDirectory();
|
|
8454
|
+
} catch {
|
|
8455
|
+
return false;
|
|
8456
|
+
}
|
|
8457
|
+
}
|
|
8458
|
+
function registerSkills(program3) {
|
|
8459
|
+
const skills = program3.command("skills").description("Install t2000 skills as local SKILL.md files (alternative to `t2000 mcp install`)");
|
|
8460
|
+
skills.command("list").description("List the skills available from t2000.ai (core t2000 + MPP recipes)").action(async () => {
|
|
8461
|
+
try {
|
|
8462
|
+
const manifest = await fetchManifest();
|
|
8463
|
+
if (isJsonMode()) {
|
|
8464
|
+
printJson({ skills: manifest.skills });
|
|
8465
|
+
return;
|
|
8466
|
+
}
|
|
8467
|
+
printBlank();
|
|
8468
|
+
printInfo(`${manifest.skills.length} skills available:`);
|
|
8469
|
+
printBlank();
|
|
8470
|
+
for (const s of manifest.skills) {
|
|
8471
|
+
console.log(` ${s.name.padEnd(28)} v${s.version}`);
|
|
8472
|
+
}
|
|
8473
|
+
printBlank();
|
|
8474
|
+
printInfo(`Install all: t2000 skills install`);
|
|
8475
|
+
printInfo(`Install one: t2000 skills install <name>`);
|
|
8476
|
+
printBlank();
|
|
8477
|
+
} catch (err) {
|
|
8478
|
+
handleError(err);
|
|
8479
|
+
}
|
|
8480
|
+
});
|
|
8481
|
+
skills.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) => {
|
|
8482
|
+
try {
|
|
8483
|
+
const target = resolveSkillTarget(opts.target);
|
|
8484
|
+
const useGlobal = opts.global === true;
|
|
8485
|
+
const manifest = await fetchManifest();
|
|
8486
|
+
const toInstall = slug ? manifest.skills.filter((s) => s.name === slug) : manifest.skills;
|
|
8487
|
+
if (toInstall.length === 0) {
|
|
8488
|
+
const available = manifest.skills.map((s) => s.name).join(", ");
|
|
8489
|
+
throw new Error(
|
|
8490
|
+
slug ? `Unknown skill: "${slug}". Available: ${available}` : "No skills found in manifest"
|
|
8491
|
+
);
|
|
8492
|
+
}
|
|
8493
|
+
const targetDir = resolveTargetDir(target, useGlobal);
|
|
8494
|
+
await mkdir5(targetDir, { recursive: true });
|
|
8495
|
+
const installed = [];
|
|
8496
|
+
for (const s of toInstall) {
|
|
8497
|
+
const raw2 = await fetchSkill(s.url);
|
|
8498
|
+
const transformed = transformForTarget(raw2, target, s.description);
|
|
8499
|
+
const relPath = filenameForTarget(s.name, target);
|
|
8500
|
+
const fullPath = join8(targetDir, relPath);
|
|
8501
|
+
await mkdir5(join8(fullPath, ".."), { recursive: true });
|
|
8502
|
+
await writeFile5(fullPath, transformed, "utf-8");
|
|
8503
|
+
installed.push({ name: s.name, path: fullPath });
|
|
8504
|
+
}
|
|
8505
|
+
if (isJsonMode()) {
|
|
8506
|
+
printJson({ target, global: useGlobal, targetDir, installed });
|
|
8507
|
+
return;
|
|
8508
|
+
}
|
|
8509
|
+
printBlank();
|
|
8510
|
+
printSuccess(`Installed ${installed.length} skill${installed.length === 1 ? "" : "s"} into ${targetDir}`);
|
|
8511
|
+
for (const r of installed) {
|
|
8512
|
+
console.log(` ${r.name}`);
|
|
8513
|
+
}
|
|
8514
|
+
printBlank();
|
|
8515
|
+
printInfo("Reload your AI client to pick up the new skill files.");
|
|
8516
|
+
if (target !== "cursor") {
|
|
8517
|
+
printInfo("(For an MCP-aware client, prefer `t2000 mcp install` \u2014 same skills, zero local files.)");
|
|
8518
|
+
}
|
|
8519
|
+
printBlank();
|
|
8520
|
+
} catch (err) {
|
|
8521
|
+
handleError(err);
|
|
8522
|
+
}
|
|
8523
|
+
});
|
|
8524
|
+
skills.command("uninstall").description("Remove installed t2000 + MPP skills from the target directory").option("--target <name>", "Target client layout: agents (default), cursor, claude-code", "agents").option("--global", "Uninstall from ~/.<target>/ instead of <cwd>/.<target>/").action(async (opts) => {
|
|
8525
|
+
try {
|
|
8526
|
+
const target = resolveSkillTarget(opts.target);
|
|
8527
|
+
const useGlobal = opts.global === true;
|
|
8528
|
+
const targetDir = resolveTargetDir(target, useGlobal);
|
|
8529
|
+
if (!await dirExists(targetDir)) {
|
|
8530
|
+
if (isJsonMode()) {
|
|
8531
|
+
printJson({ target, targetDir, removed: [] });
|
|
8532
|
+
return;
|
|
8533
|
+
}
|
|
8534
|
+
printInfo(`No skills installed at ${targetDir}`);
|
|
8535
|
+
return;
|
|
8536
|
+
}
|
|
8537
|
+
const entries = await readdir(targetDir);
|
|
8538
|
+
const removed = [];
|
|
8539
|
+
for (const entry of entries) {
|
|
8540
|
+
const full = join8(targetDir, entry);
|
|
8541
|
+
if (target === "cursor") {
|
|
8542
|
+
const slug = entry.endsWith(".mdc") ? entry.slice(0, -".mdc".length) : entry;
|
|
8543
|
+
if (entry.endsWith(".mdc") && isManagedSkillName(slug)) {
|
|
8544
|
+
await unlink2(full);
|
|
8545
|
+
removed.push(entry);
|
|
8546
|
+
}
|
|
8547
|
+
} else {
|
|
8548
|
+
if (isManagedSkillName(entry)) {
|
|
8549
|
+
const skillFile = join8(full, "SKILL.md");
|
|
8550
|
+
try {
|
|
8551
|
+
await unlink2(skillFile);
|
|
8552
|
+
} catch {
|
|
8553
|
+
}
|
|
8554
|
+
try {
|
|
8555
|
+
await rmdir(full);
|
|
8556
|
+
} catch {
|
|
8557
|
+
}
|
|
8558
|
+
removed.push(entry);
|
|
8559
|
+
}
|
|
8560
|
+
}
|
|
8561
|
+
}
|
|
8562
|
+
if (isJsonMode()) {
|
|
8563
|
+
printJson({ target, targetDir, removed });
|
|
8564
|
+
return;
|
|
8565
|
+
}
|
|
8566
|
+
printBlank();
|
|
8567
|
+
if (removed.length === 0) {
|
|
8568
|
+
printInfo(`No managed skills found in ${targetDir}`);
|
|
8569
|
+
} else {
|
|
8570
|
+
printSuccess(`Removed ${removed.length} skill${removed.length === 1 ? "" : "s"} from ${targetDir}`);
|
|
8571
|
+
}
|
|
8572
|
+
printBlank();
|
|
8573
|
+
} catch (err) {
|
|
8574
|
+
handleError(err);
|
|
8575
|
+
}
|
|
8576
|
+
});
|
|
8577
|
+
}
|
|
8578
|
+
|
|
8421
8579
|
// src/program.ts
|
|
8422
8580
|
var require2 = createRequire(import.meta.url);
|
|
8423
8581
|
var { version: CLI_VERSION } = require2("../package.json");
|
|
8424
8582
|
function createProgram() {
|
|
8425
8583
|
const program3 = new Command();
|
|
8426
|
-
program3.name("t2000").description("
|
|
8584
|
+
program3.name("t2000").description("Agentic Wallet for AI agents").version(`${CLI_VERSION} (beta)`).option("--json", "Output in JSON format").hook("preAction", (thisCommand) => {
|
|
8427
8585
|
const opts = thisCommand.optsWithGlobals();
|
|
8428
8586
|
if (opts.json) setJsonMode(true);
|
|
8429
8587
|
}).addHelpText("after", `
|
|
8430
8588
|
Examples:
|
|
8431
|
-
$ t2000 init Create a new
|
|
8589
|
+
$ t2000 init Create a new Agentic Wallet
|
|
8590
|
+
$ t2000 fund Show how to fund your wallet
|
|
8432
8591
|
$ t2000 balance Show wallet balance
|
|
8433
|
-
$ t2000 save 100 Save $100 to earn yield
|
|
8434
|
-
$ t2000
|
|
8592
|
+
$ t2000 save 100 Save $100 USDC to earn yield
|
|
8593
|
+
$ t2000 save 50 --asset USDsui Save 50 USDsui to NAVI
|
|
8594
|
+
$ t2000 send 50 to 0xabc... Send $50 USDC
|
|
8595
|
+
$ t2000 receive --amount 25 Generate a payment link
|
|
8596
|
+
$ t2000 swap 100 USDC SUI Swap 100 USDC for SUI
|
|
8435
8597
|
$ t2000 borrow 200 Borrow $200 against savings
|
|
8436
8598
|
$ t2000 pay openai ... Pay for an API via MPP gateway
|
|
8437
|
-
$ t2000 mcp install
|
|
8599
|
+
$ t2000 mcp install Connect Claude / Cursor / Windsurf (all skills come along as MCP prompts)
|
|
8600
|
+
$ t2000 skills install Install skills as local SKILL.md files (alternative to MCP)`);
|
|
8438
8601
|
registerInit(program3);
|
|
8439
8602
|
registerSend(program3);
|
|
8440
8603
|
registerBalance(program3);
|
|
8441
8604
|
registerAddress(program3);
|
|
8442
|
-
|
|
8605
|
+
registerFund(program3);
|
|
8443
8606
|
registerHistory(program3);
|
|
8444
8607
|
registerExport(program3);
|
|
8445
8608
|
registerImport(program3);
|
|
@@ -8462,9 +8625,8 @@ Examples:
|
|
|
8462
8625
|
registerClaimRewards(program3);
|
|
8463
8626
|
registerSwap(program3);
|
|
8464
8627
|
registerSwapQuote(program3);
|
|
8465
|
-
registerStake(program3);
|
|
8466
|
-
registerUnstake(program3);
|
|
8467
8628
|
registerReceive(program3);
|
|
8629
|
+
registerSkills(program3);
|
|
8468
8630
|
return program3;
|
|
8469
8631
|
}
|
|
8470
8632
|
|