@cabaltrading/cli 0.4.4 → 0.4.5

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/index.js CHANGED
@@ -642,34 +642,9 @@ var init_agents = __esm(() => {
642
642
 
643
643
  // ../../packages/client/src/schemas/trade.ts
644
644
  import { z as z4 } from "zod";
645
- var SUPPORTED_MODELS, modelSchema, solanaTradeRequestSchema, hyperliquidTradeRequestSchema, tradeRequestSchema, tradeResponseDataSchema, tradeResponseSchema, dryRunResponseDataSchema;
645
+ var solanaTradeRequestSchema, hyperliquidTradeRequestSchema, tradeRequestSchema, tradeResponseDataSchema, tradeResponseSchema, dryRunResponseDataSchema;
646
646
  var init_trade = __esm(() => {
647
647
  init_common();
648
- SUPPORTED_MODELS = [
649
- "claude-3-opus",
650
- "claude-3-sonnet",
651
- "claude-3.5-sonnet",
652
- "claude-3-haiku",
653
- "gpt-4",
654
- "gpt-4-turbo",
655
- "gpt-4o",
656
- "o1",
657
- "o1-mini",
658
- "grok-2",
659
- "grok-2-mini",
660
- "gemini-pro",
661
- "gemini-ultra",
662
- "llama-3-70b",
663
- "llama-3-405b",
664
- "mistral-large",
665
- "mixtral",
666
- "deepseek-v3",
667
- "deepseek-r1",
668
- "kimi-k2",
669
- "kimi-k2.5",
670
- "other"
671
- ];
672
- modelSchema = z4.enum(SUPPORTED_MODELS);
673
648
  solanaTradeRequestSchema = z4.object({
674
649
  chain: z4.literal("solana"),
675
650
  inputToken: z4.string().min(1),
@@ -677,7 +652,7 @@ var init_trade = __esm(() => {
677
652
  amount: z4.number().positive(),
678
653
  slippageBps: z4.number().int().min(1).max(500).optional(),
679
654
  dryRun: z4.boolean().optional(),
680
- model: modelSchema.optional()
655
+ model: z4.string().optional()
681
656
  });
682
657
  hyperliquidTradeRequestSchema = z4.object({
683
658
  chain: z4.literal("hyperliquid"),
@@ -687,7 +662,7 @@ var init_trade = __esm(() => {
687
662
  price: z4.number().positive().optional(),
688
663
  orderType: z4.enum(["limit", "market"]).optional(),
689
664
  leverage: z4.number().positive().optional(),
690
- model: modelSchema.optional()
665
+ model: z4.string().optional()
691
666
  });
692
667
  tradeRequestSchema = z4.discriminatedUnion("chain", [
693
668
  solanaTradeRequestSchema,
@@ -3663,6 +3638,232 @@ var init_env = __esm(() => {
3663
3638
  ];
3664
3639
  });
3665
3640
 
3641
+ // ../../packages/solana/src/errors.ts
3642
+ function def(code, name, message, program, retryable = false, suggestion) {
3643
+ return { code, hex: `0x${code.toString(16)}`, name, message, retryable, suggestion, program };
3644
+ }
3645
+ function parseSolanaError(message) {
3646
+ if (!message)
3647
+ return null;
3648
+ const customMatch = CUSTOM_ERROR_RE.exec(message);
3649
+ if (customMatch) {
3650
+ const code = parseInt(customMatch[1], 16);
3651
+ const hex = `0x${customMatch[1].toLowerCase()}`;
3652
+ const instructionMatch = INSTRUCTION_INDEX_RE.exec(message);
3653
+ const instructionIndex = instructionMatch ? parseInt(instructionMatch[1], 10) : undefined;
3654
+ return {
3655
+ type: "custom",
3656
+ code,
3657
+ hex,
3658
+ instructionIndex,
3659
+ def: PROGRAM_ERRORS.get(code),
3660
+ raw: message
3661
+ };
3662
+ }
3663
+ const anchorMatch = ANCHOR_ERROR_RE.exec(message);
3664
+ if (anchorMatch) {
3665
+ const code = parseInt(anchorMatch[1], 10);
3666
+ return {
3667
+ type: "custom",
3668
+ code,
3669
+ hex: `0x${code.toString(16)}`,
3670
+ def: PROGRAM_ERRORS.get(code),
3671
+ raw: message
3672
+ };
3673
+ }
3674
+ for (const [variant, errorDef] of INSTRUCTION_ERRORS) {
3675
+ if (message.includes(variant)) {
3676
+ return {
3677
+ type: "instruction",
3678
+ def: errorDef,
3679
+ raw: message
3680
+ };
3681
+ }
3682
+ }
3683
+ return null;
3684
+ }
3685
+ function classifyTradeError(errorMessage) {
3686
+ const parsed = parseSolanaError(errorMessage);
3687
+ if (parsed?.def) {
3688
+ const d = parsed.def;
3689
+ if (d.name === "SlippageToleranceExceeded") {
3690
+ return {
3691
+ errorCode: "BAD_REQUEST",
3692
+ httpStatus: 400,
3693
+ message: d.message,
3694
+ retryable: true,
3695
+ suggestion: d.suggestion,
3696
+ solanaError: d.name
3697
+ };
3698
+ }
3699
+ if (d.name === "InsufficientFunds") {
3700
+ return {
3701
+ errorCode: "BAD_REQUEST",
3702
+ httpStatus: 400,
3703
+ message: d.message,
3704
+ retryable: false,
3705
+ suggestion: d.suggestion,
3706
+ solanaError: d.name
3707
+ };
3708
+ }
3709
+ if (d.name === "ComputationalBudgetExceeded" || d.name === "ProgramFailedToComplete") {
3710
+ return {
3711
+ errorCode: "DEPENDENCY_ERROR",
3712
+ httpStatus: 502,
3713
+ message: d.message,
3714
+ retryable: true,
3715
+ suggestion: d.suggestion,
3716
+ solanaError: d.name
3717
+ };
3718
+ }
3719
+ return {
3720
+ errorCode: d.retryable ? "DEPENDENCY_ERROR" : "BAD_REQUEST",
3721
+ httpStatus: d.retryable ? 502 : 400,
3722
+ message: d.message,
3723
+ retryable: d.retryable,
3724
+ suggestion: d.suggestion,
3725
+ solanaError: d.name
3726
+ };
3727
+ }
3728
+ if (parsed?.type === "custom" && parsed.code !== undefined) {
3729
+ return {
3730
+ errorCode: "INTERNAL_ERROR",
3731
+ httpStatus: 500,
3732
+ message: `Transaction failed with program error ${parsed.hex}`,
3733
+ retryable: false,
3734
+ solanaError: `UnknownError_${parsed.hex}`
3735
+ };
3736
+ }
3737
+ for (const pattern of KEYWORD_PATTERNS) {
3738
+ if (pattern.test(errorMessage)) {
3739
+ return pattern.classify(errorMessage);
3740
+ }
3741
+ }
3742
+ return {
3743
+ errorCode: "INTERNAL_ERROR",
3744
+ httpStatus: 500,
3745
+ message: `Trade failed: ${errorMessage}`,
3746
+ retryable: false
3747
+ };
3748
+ }
3749
+ var PROGRAM_ERRORS, INSTRUCTION_ERRORS, CUSTOM_ERROR_RE, INSTRUCTION_INDEX_RE, ANCHOR_ERROR_RE, KEYWORD_PATTERNS;
3750
+ var init_errors2 = __esm(() => {
3751
+ PROGRAM_ERRORS = new Map([
3752
+ [0, def(0, "NotRentExempt", "Account is not rent exempt", "token")],
3753
+ [1, def(1, "InsufficientFunds", "Insufficient token balance", "token", false, "Check your token balance before trading")],
3754
+ [2, def(2, "InvalidMint", "Invalid mint address", "token")],
3755
+ [3, def(3, "MintMismatch", "Account mint does not match expected mint", "token")],
3756
+ [4, def(4, "OwnerMismatch", "Account owner does not match expected owner", "token")],
3757
+ [5, def(5, "FixedSupply", "Token supply is fixed — cannot mint more", "token")],
3758
+ [6, def(6, "AlreadyInUse", "Account is already initialized", "token")],
3759
+ [7, def(7, "InvalidNumberOfProvidedSigners", "Invalid number of signers", "token")],
3760
+ [8, def(8, "InvalidNumberOfRequiredSigners", "Invalid number of required signers", "token")],
3761
+ [9, def(9, "UninitializedState", "Token account is not initialized", "token")],
3762
+ [10, def(10, "NativeNotSupported", "Operation not supported for native SOL", "token")],
3763
+ [11, def(11, "NonNativeHasBalance", "Non-native account has balance — close with non-zero balance", "token")],
3764
+ [12, def(12, "InvalidInstruction", "Invalid token instruction", "token")],
3765
+ [13, def(13, "InvalidState", "Invalid token account state", "token")],
3766
+ [14, def(14, "Overflow", "Arithmetic overflow in token operation", "token")],
3767
+ [15, def(15, "AuthorityTypeNotSupported", "Authority type not supported", "token")],
3768
+ [16, def(16, "MintCannotFreeze", "This mint cannot freeze accounts", "token")],
3769
+ [17, def(17, "AccountFrozen", "Account is frozen — cannot transfer", "token")],
3770
+ [6000, def(6000, "EmptyRoute", "No swap route found", "jupiter", false, "Token pair may not have liquidity. Try a different pair.")],
3771
+ [6001, def(6001, "SlippageToleranceExceeded", "Slippage tolerance exceeded — price moved during execution", "jupiter", true, "Retry or increase slippage tolerance")],
3772
+ [6002, def(6002, "InvalidCalculation", "Swap calculation error", "jupiter")],
3773
+ [6003, def(6003, "MissingPlatformFeeAccount", "Platform fee account not provided", "jupiter", false, "Server configuration issue — contact support")],
3774
+ [6004, def(6004, "InvalidSlippage", "Invalid slippage value", "jupiter")],
3775
+ [6005, def(6005, "NotEnoughPercent", "Split percent does not sum to 100", "jupiter")],
3776
+ [6006, def(6006, "InvalidInputIndex", "Invalid route input index", "jupiter")],
3777
+ [6007, def(6007, "InvalidOutputIndex", "Invalid route output index", "jupiter")],
3778
+ [6008, def(6008, "NotEnoughAccountKeys", "Not enough account keys for instruction", "jupiter")],
3779
+ [6009, def(6009, "NonZeroMinimumOutAmountNotSupported", "Non-zero minimum out amount not supported for this route", "jupiter")],
3780
+ [6010, def(6010, "InvalidRoutePlan", "Invalid route plan", "jupiter")],
3781
+ [6011, def(6011, "InvalidReferralAuthority", "Invalid referral authority", "jupiter")],
3782
+ [6012, def(6012, "LedgerTokenAccountDoesNotMatch", "Token ledger account mismatch", "jupiter")],
3783
+ [6013, def(6013, "InvalidTokenLedger", "Invalid token ledger state", "jupiter")],
3784
+ [6014, def(6014, "IncorrectTokenProgramID", "Incorrect token program ID", "jupiter")],
3785
+ [6015, def(6015, "TokenProgramNotProvided", "Token program not provided", "jupiter")],
3786
+ [6016, def(6016, "SwapNotSupported", "This swap is not supported", "jupiter")],
3787
+ [6017, def(6017, "ExactOutAmountNotMatched", "Exact output amount not met", "jupiter")],
3788
+ [6025, def(6025, "InvalidTokenAccount", "Invalid token account for platform fee", "jupiter", false, "Platform fee account may not be initialized — contact support")]
3789
+ ]);
3790
+ INSTRUCTION_ERRORS = new Map([
3791
+ ["InsufficientFunds", def(0, "InsufficientFunds", "Insufficient SOL for transaction fees", "system", false, "Fund your wallet with SOL for gas")],
3792
+ ["InvalidAccountData", def(0, "InvalidAccountData", "Account data is invalid or corrupt", "system")],
3793
+ ["AccountAlreadyInUse", def(0, "AccountAlreadyInUse", "Account is already in use", "system")],
3794
+ ["AccountNotFound", def(0, "AccountNotFound", "Account not found on chain", "system")],
3795
+ ["InvalidArgument", def(0, "InvalidArgument", "Invalid instruction argument", "system")],
3796
+ ["InvalidInstructionData", def(0, "InvalidInstructionData", "Invalid instruction data", "system")],
3797
+ ["InvalidAccountOwner", def(0, "InvalidAccountOwner", "Account is not owned by the expected program", "system")],
3798
+ ["ComputationalBudgetExceeded", def(0, "ComputationalBudgetExceeded", "Transaction exceeded compute budget", "compute-budget", true, "Retry — the transaction was too complex for the allocated compute units")],
3799
+ ["ProgramFailedToComplete", def(0, "ProgramFailedToComplete", "Program failed to complete", "system", true, "Retry — may be a transient issue")]
3800
+ ]);
3801
+ CUSTOM_ERROR_RE = /custom program error: 0x([0-9a-fA-F]+)/i;
3802
+ INSTRUCTION_INDEX_RE = /Error processing Instruction (\d+):/i;
3803
+ ANCHOR_ERROR_RE = /Error Number: (\d+)/i;
3804
+ KEYWORD_PATTERNS = [
3805
+ {
3806
+ test: (msg) => /insufficient\s*(funds|balance|lamports)/i.test(msg) || msg.toLowerCase().includes("insufficient balance"),
3807
+ classify: () => ({
3808
+ errorCode: "BAD_REQUEST",
3809
+ httpStatus: 400,
3810
+ message: "Insufficient balance to complete this trade",
3811
+ retryable: false,
3812
+ suggestion: "Check your wallet balance before trading",
3813
+ solanaError: "InsufficientFunds"
3814
+ })
3815
+ },
3816
+ {
3817
+ test: (msg) => msg.toLowerCase().includes("slippage"),
3818
+ classify: () => ({
3819
+ errorCode: "BAD_REQUEST",
3820
+ httpStatus: 400,
3821
+ message: "Slippage tolerance exceeded — price moved during execution",
3822
+ retryable: true,
3823
+ suggestion: "Retry or increase slippage tolerance",
3824
+ solanaError: "SlippageToleranceExceeded"
3825
+ })
3826
+ },
3827
+ {
3828
+ test: (msg) => {
3829
+ const lower = msg.toLowerCase();
3830
+ return lower.includes("expired") || lower.includes("blockhash not found") || lower.includes("block height exceeded");
3831
+ },
3832
+ classify: () => ({
3833
+ errorCode: "DEPENDENCY_ERROR",
3834
+ httpStatus: 502,
3835
+ message: "Transaction expired before confirmation",
3836
+ retryable: true,
3837
+ suggestion: "This is transient — retry with a fresh quote",
3838
+ solanaError: "TransactionExpired"
3839
+ })
3840
+ },
3841
+ {
3842
+ test: (msg) => msg.toLowerCase().includes("rate limit"),
3843
+ classify: (msg) => ({
3844
+ errorCode: "RATE_LIMITED",
3845
+ httpStatus: 429,
3846
+ message: msg,
3847
+ retryable: false,
3848
+ suggestion: "Wait a moment before retrying"
3849
+ })
3850
+ },
3851
+ {
3852
+ test: (msg) => {
3853
+ const lower = msg.toLowerCase();
3854
+ return lower.includes("unknown token") || lower.includes("token not found");
3855
+ },
3856
+ classify: (msg) => ({
3857
+ errorCode: "BAD_REQUEST",
3858
+ httpStatus: 400,
3859
+ message: msg,
3860
+ retryable: false,
3861
+ suggestion: "Use a known symbol (SOL, USDC, BONK, WIF) or pass a raw mint address"
3862
+ })
3863
+ }
3864
+ ];
3865
+ });
3866
+
3666
3867
  // src/lib/errors.ts
3667
3868
  import chalk from "chalk";
3668
3869
  function normalizeCliError(error) {
@@ -3691,43 +3892,12 @@ function printCliError(error) {
3691
3892
  }
3692
3893
  function mapTradeError(error) {
3693
3894
  const normalized = normalizeCliError(error);
3694
- const msg = normalized.message.toLowerCase();
3695
- if (msg.includes("slippage") || msg.includes("0x1789") || msg.includes("6025")) {
3696
- return {
3697
- message: "Slippage exceeded — price moved too much during execution",
3698
- suggestion: "Retry with higher slippage: --slippage 300",
3699
- retryable: true
3700
- };
3701
- }
3702
- if (msg.includes("expired") || msg.includes("blockhash")) {
3703
- return {
3704
- message: "Transaction expired — took too long to confirm",
3705
- suggestion: "This is transient. Try again.",
3706
- retryable: true
3707
- };
3708
- }
3709
- if (msg.includes("insufficient balance") || msg.includes("insufficient funds") || msg.includes("0x1")) {
3710
- return {
3711
- message: "Insufficient balance",
3712
- suggestion: "Check your balance with: cabal-cli status",
3713
- retryable: false
3714
- };
3715
- }
3716
- if (msg.includes("rate limit")) {
3717
- return {
3718
- message: normalized.message,
3719
- suggestion: "Wait a moment before retrying.",
3720
- retryable: false
3721
- };
3722
- }
3723
- if (msg.includes("unknown token") || msg.includes("token not found")) {
3724
- return {
3725
- message: normalized.message,
3726
- suggestion: "Use a known symbol (SOL, USDC, BONK, WIF) or pass a raw mint address.",
3727
- retryable: false
3728
- };
3729
- }
3730
- return { message: normalized.message, retryable: false };
3895
+ const classified = classifyTradeError(normalized.message);
3896
+ return {
3897
+ message: classified.message,
3898
+ suggestion: classified.suggestion,
3899
+ retryable: classified.retryable
3900
+ };
3731
3901
  }
3732
3902
  function printTradeError(error) {
3733
3903
  const mapped = mapTradeError(error);
@@ -3749,8 +3919,9 @@ function toStructuredError(error) {
3749
3919
  }
3750
3920
  };
3751
3921
  }
3752
- var init_errors2 = __esm(() => {
3922
+ var init_errors3 = __esm(() => {
3753
3923
  init_src();
3924
+ init_errors2();
3754
3925
  });
3755
3926
 
3756
3927
  // src/mcp/server.ts
@@ -3800,7 +3971,7 @@ async function createServer() {
3800
3971
  size: z22.number().optional().describe("Hyperliquid: position size"),
3801
3972
  orderType: z22.enum(["market", "limit"]).optional().describe("Hyperliquid: order type (default: market)"),
3802
3973
  price: z22.number().optional().describe("Hyperliquid: limit price (required for limit orders)"),
3803
- model: modelSchema.optional().describe("AI model name for attribution")
3974
+ model: z22.string().optional().describe("AI model name for attribution")
3804
3975
  };
3805
3976
  server.tool("cabal_trade", "Execute a trade on Solana (Jupiter swap) or Hyperliquid (perps/spot). Set dryRun: true to preview without executing, or use cabal_quote for Solana quotes.", tradeSchema, async (params) => {
3806
3977
  if (params.chain === "solana") {
@@ -4018,7 +4189,7 @@ Describe: (1) what triggers it, (2) how it unfolds, (3) what it looks like after
4018
4189
  var init_server = __esm(() => {
4019
4190
  init_src();
4020
4191
  init_env();
4021
- init_errors2();
4192
+ init_errors3();
4022
4193
  });
4023
4194
 
4024
4195
  // src/lib/browser.ts
@@ -4160,7 +4331,7 @@ var init_login = __esm(() => {
4160
4331
  init_src();
4161
4332
  init_browser();
4162
4333
  init_env();
4163
- init_errors2();
4334
+ init_errors3();
4164
4335
  TIMEOUT_MS = 10 * 60 * 1000;
4165
4336
  });
4166
4337
 
@@ -4930,7 +5101,7 @@ var STEP_ORDER;
4930
5101
  var init_onboard = __esm(() => {
4931
5102
  init_src();
4932
5103
  init_env();
4933
- init_errors2();
5104
+ init_errors3();
4934
5105
  init_browser();
4935
5106
  init_login();
4936
5107
  STEP_ORDER = ["connect", "profile", "avatar", "verify", "hyperliquid"];
@@ -5025,7 +5196,7 @@ function formatPnl(value, percent) {
5025
5196
  var init_status = __esm(() => {
5026
5197
  init_src();
5027
5198
  init_env();
5028
- init_errors2();
5199
+ init_errors3();
5029
5200
  });
5030
5201
 
5031
5202
  // src/commands/trade.ts
@@ -5116,7 +5287,7 @@ async function tradeCommand(options) {
5116
5287
  outputToken: outputToken.trim().toUpperCase(),
5117
5288
  amount,
5118
5289
  slippageBps,
5119
- ...options.model && { model: modelSchema.parse(options.model) }
5290
+ ...options.model && { model: options.model }
5120
5291
  };
5121
5292
  } else if (chain === "hyperliquid") {
5122
5293
  if (!isTTY()) {
@@ -5168,7 +5339,7 @@ async function tradeCommand(options) {
5168
5339
  size,
5169
5340
  orderType,
5170
5341
  ...price && { price },
5171
- ...options.model && { model: modelSchema.parse(options.model) }
5342
+ ...options.model && { model: options.model }
5172
5343
  };
5173
5344
  } else {
5174
5345
  console.log(chalk5.red(`Error: Unknown chain "${chain}". Use "solana" or "hyperliquid".`));
@@ -5269,7 +5440,7 @@ async function tradeCommand(options) {
5269
5440
  var init_trade2 = __esm(() => {
5270
5441
  init_src();
5271
5442
  init_env();
5272
- init_errors2();
5443
+ init_errors3();
5273
5444
  });
5274
5445
 
5275
5446
  // src/commands/post.ts
@@ -5327,7 +5498,7 @@ async function postCommand(options) {
5327
5498
  var init_post = __esm(() => {
5328
5499
  init_src();
5329
5500
  init_env();
5330
- init_errors2();
5501
+ init_errors3();
5331
5502
  });
5332
5503
 
5333
5504
  // src/commands/feed.ts
@@ -5398,7 +5569,7 @@ function formatAge(dateStr) {
5398
5569
  var init_feed = __esm(() => {
5399
5570
  init_src();
5400
5571
  init_env();
5401
- init_errors2();
5572
+ init_errors3();
5402
5573
  });
5403
5574
 
5404
5575
  // src/commands/leaderboard.ts
@@ -5468,7 +5639,7 @@ function formatUsd(value) {
5468
5639
  var init_leaderboard2 = __esm(() => {
5469
5640
  init_src();
5470
5641
  init_env();
5471
- init_errors2();
5642
+ init_errors3();
5472
5643
  });
5473
5644
 
5474
5645
  // src/commands/comment.ts
@@ -5505,7 +5676,7 @@ async function commentCommand(postId, body) {
5505
5676
  var init_comment = __esm(() => {
5506
5677
  init_src();
5507
5678
  init_env();
5508
- init_errors2();
5679
+ init_errors3();
5509
5680
  });
5510
5681
 
5511
5682
  // src/commands/vote.ts
@@ -5545,7 +5716,7 @@ async function voteCommand(postId, direction) {
5545
5716
  var init_vote = __esm(() => {
5546
5717
  init_src();
5547
5718
  init_env();
5548
- init_errors2();
5719
+ init_errors3();
5549
5720
  });
5550
5721
 
5551
5722
  // src/commands/image.ts
@@ -5593,7 +5764,7 @@ async function imageCommand(options) {
5593
5764
  var init_image = __esm(() => {
5594
5765
  init_src();
5595
5766
  init_env();
5596
- init_errors2();
5767
+ init_errors3();
5597
5768
  });
5598
5769
 
5599
5770
  // src/commands/video.ts
@@ -5675,7 +5846,7 @@ var VIDEO_ASPECT_RATIOS;
5675
5846
  var init_video = __esm(() => {
5676
5847
  init_src();
5677
5848
  init_env();
5678
- init_errors2();
5849
+ init_errors3();
5679
5850
  VIDEO_ASPECT_RATIOS = ["landscape", "portrait", "16:9", "4:3", "1:1", "3:4", "9:16"];
5680
5851
  });
5681
5852
 
@@ -5809,7 +5980,7 @@ function getStatusBadge3(status) {
5809
5980
  var init_token = __esm(() => {
5810
5981
  init_src();
5811
5982
  init_env();
5812
- init_errors2();
5983
+ init_errors3();
5813
5984
  });
5814
5985
 
5815
5986
  // src/commands/skill.ts
@@ -5986,7 +6157,7 @@ function formatBytes(bytes) {
5986
6157
  var MANIFEST_FILE = ".cabal-skills.json", skillManifestSchema;
5987
6158
  var init_skill = __esm(() => {
5988
6159
  init_env();
5989
- init_errors2();
6160
+ init_errors3();
5990
6161
  skillManifestSchema = z26.object({
5991
6162
  files: z26.record(z26.string(), z26.string()).optional().default({}),
5992
6163
  descriptions: z26.record(z26.string(), z26.string()).optional().default({})
@@ -6104,7 +6275,7 @@ function formatPnl3(pnl) {
6104
6275
  var init_hl = __esm(() => {
6105
6276
  init_src();
6106
6277
  init_env();
6107
- init_errors2();
6278
+ init_errors3();
6108
6279
  });
6109
6280
 
6110
6281
  // src/index.ts
@@ -641,34 +641,9 @@ var init_agents = __esm(() => {
641
641
 
642
642
  // ../../packages/client/src/schemas/trade.ts
643
643
  import { z as z4 } from "zod";
644
- var SUPPORTED_MODELS, modelSchema, solanaTradeRequestSchema, hyperliquidTradeRequestSchema, tradeRequestSchema, tradeResponseDataSchema, tradeResponseSchema, dryRunResponseDataSchema;
644
+ var solanaTradeRequestSchema, hyperliquidTradeRequestSchema, tradeRequestSchema, tradeResponseDataSchema, tradeResponseSchema, dryRunResponseDataSchema;
645
645
  var init_trade = __esm(() => {
646
646
  init_common();
647
- SUPPORTED_MODELS = [
648
- "claude-3-opus",
649
- "claude-3-sonnet",
650
- "claude-3.5-sonnet",
651
- "claude-3-haiku",
652
- "gpt-4",
653
- "gpt-4-turbo",
654
- "gpt-4o",
655
- "o1",
656
- "o1-mini",
657
- "grok-2",
658
- "grok-2-mini",
659
- "gemini-pro",
660
- "gemini-ultra",
661
- "llama-3-70b",
662
- "llama-3-405b",
663
- "mistral-large",
664
- "mixtral",
665
- "deepseek-v3",
666
- "deepseek-r1",
667
- "kimi-k2",
668
- "kimi-k2.5",
669
- "other"
670
- ];
671
- modelSchema = z4.enum(SUPPORTED_MODELS);
672
647
  solanaTradeRequestSchema = z4.object({
673
648
  chain: z4.literal("solana"),
674
649
  inputToken: z4.string().min(1),
@@ -676,7 +651,7 @@ var init_trade = __esm(() => {
676
651
  amount: z4.number().positive(),
677
652
  slippageBps: z4.number().int().min(1).max(500).optional(),
678
653
  dryRun: z4.boolean().optional(),
679
- model: modelSchema.optional()
654
+ model: z4.string().optional()
680
655
  });
681
656
  hyperliquidTradeRequestSchema = z4.object({
682
657
  chain: z4.literal("hyperliquid"),
@@ -686,7 +661,7 @@ var init_trade = __esm(() => {
686
661
  price: z4.number().positive().optional(),
687
662
  orderType: z4.enum(["limit", "market"]).optional(),
688
663
  leverage: z4.number().positive().optional(),
689
- model: modelSchema.optional()
664
+ model: z4.string().optional()
690
665
  });
691
666
  tradeRequestSchema = z4.discriminatedUnion("chain", [
692
667
  solanaTradeRequestSchema,
@@ -3662,6 +3637,232 @@ var init_env = __esm(() => {
3662
3637
  ];
3663
3638
  });
3664
3639
 
3640
+ // ../../packages/solana/src/errors.ts
3641
+ function def(code, name, message, program, retryable = false, suggestion) {
3642
+ return { code, hex: `0x${code.toString(16)}`, name, message, retryable, suggestion, program };
3643
+ }
3644
+ function parseSolanaError(message) {
3645
+ if (!message)
3646
+ return null;
3647
+ const customMatch = CUSTOM_ERROR_RE.exec(message);
3648
+ if (customMatch) {
3649
+ const code = parseInt(customMatch[1], 16);
3650
+ const hex = `0x${customMatch[1].toLowerCase()}`;
3651
+ const instructionMatch = INSTRUCTION_INDEX_RE.exec(message);
3652
+ const instructionIndex = instructionMatch ? parseInt(instructionMatch[1], 10) : undefined;
3653
+ return {
3654
+ type: "custom",
3655
+ code,
3656
+ hex,
3657
+ instructionIndex,
3658
+ def: PROGRAM_ERRORS.get(code),
3659
+ raw: message
3660
+ };
3661
+ }
3662
+ const anchorMatch = ANCHOR_ERROR_RE.exec(message);
3663
+ if (anchorMatch) {
3664
+ const code = parseInt(anchorMatch[1], 10);
3665
+ return {
3666
+ type: "custom",
3667
+ code,
3668
+ hex: `0x${code.toString(16)}`,
3669
+ def: PROGRAM_ERRORS.get(code),
3670
+ raw: message
3671
+ };
3672
+ }
3673
+ for (const [variant, errorDef] of INSTRUCTION_ERRORS) {
3674
+ if (message.includes(variant)) {
3675
+ return {
3676
+ type: "instruction",
3677
+ def: errorDef,
3678
+ raw: message
3679
+ };
3680
+ }
3681
+ }
3682
+ return null;
3683
+ }
3684
+ function classifyTradeError(errorMessage) {
3685
+ const parsed = parseSolanaError(errorMessage);
3686
+ if (parsed?.def) {
3687
+ const d = parsed.def;
3688
+ if (d.name === "SlippageToleranceExceeded") {
3689
+ return {
3690
+ errorCode: "BAD_REQUEST",
3691
+ httpStatus: 400,
3692
+ message: d.message,
3693
+ retryable: true,
3694
+ suggestion: d.suggestion,
3695
+ solanaError: d.name
3696
+ };
3697
+ }
3698
+ if (d.name === "InsufficientFunds") {
3699
+ return {
3700
+ errorCode: "BAD_REQUEST",
3701
+ httpStatus: 400,
3702
+ message: d.message,
3703
+ retryable: false,
3704
+ suggestion: d.suggestion,
3705
+ solanaError: d.name
3706
+ };
3707
+ }
3708
+ if (d.name === "ComputationalBudgetExceeded" || d.name === "ProgramFailedToComplete") {
3709
+ return {
3710
+ errorCode: "DEPENDENCY_ERROR",
3711
+ httpStatus: 502,
3712
+ message: d.message,
3713
+ retryable: true,
3714
+ suggestion: d.suggestion,
3715
+ solanaError: d.name
3716
+ };
3717
+ }
3718
+ return {
3719
+ errorCode: d.retryable ? "DEPENDENCY_ERROR" : "BAD_REQUEST",
3720
+ httpStatus: d.retryable ? 502 : 400,
3721
+ message: d.message,
3722
+ retryable: d.retryable,
3723
+ suggestion: d.suggestion,
3724
+ solanaError: d.name
3725
+ };
3726
+ }
3727
+ if (parsed?.type === "custom" && parsed.code !== undefined) {
3728
+ return {
3729
+ errorCode: "INTERNAL_ERROR",
3730
+ httpStatus: 500,
3731
+ message: `Transaction failed with program error ${parsed.hex}`,
3732
+ retryable: false,
3733
+ solanaError: `UnknownError_${parsed.hex}`
3734
+ };
3735
+ }
3736
+ for (const pattern of KEYWORD_PATTERNS) {
3737
+ if (pattern.test(errorMessage)) {
3738
+ return pattern.classify(errorMessage);
3739
+ }
3740
+ }
3741
+ return {
3742
+ errorCode: "INTERNAL_ERROR",
3743
+ httpStatus: 500,
3744
+ message: `Trade failed: ${errorMessage}`,
3745
+ retryable: false
3746
+ };
3747
+ }
3748
+ var PROGRAM_ERRORS, INSTRUCTION_ERRORS, CUSTOM_ERROR_RE, INSTRUCTION_INDEX_RE, ANCHOR_ERROR_RE, KEYWORD_PATTERNS;
3749
+ var init_errors2 = __esm(() => {
3750
+ PROGRAM_ERRORS = new Map([
3751
+ [0, def(0, "NotRentExempt", "Account is not rent exempt", "token")],
3752
+ [1, def(1, "InsufficientFunds", "Insufficient token balance", "token", false, "Check your token balance before trading")],
3753
+ [2, def(2, "InvalidMint", "Invalid mint address", "token")],
3754
+ [3, def(3, "MintMismatch", "Account mint does not match expected mint", "token")],
3755
+ [4, def(4, "OwnerMismatch", "Account owner does not match expected owner", "token")],
3756
+ [5, def(5, "FixedSupply", "Token supply is fixed — cannot mint more", "token")],
3757
+ [6, def(6, "AlreadyInUse", "Account is already initialized", "token")],
3758
+ [7, def(7, "InvalidNumberOfProvidedSigners", "Invalid number of signers", "token")],
3759
+ [8, def(8, "InvalidNumberOfRequiredSigners", "Invalid number of required signers", "token")],
3760
+ [9, def(9, "UninitializedState", "Token account is not initialized", "token")],
3761
+ [10, def(10, "NativeNotSupported", "Operation not supported for native SOL", "token")],
3762
+ [11, def(11, "NonNativeHasBalance", "Non-native account has balance — close with non-zero balance", "token")],
3763
+ [12, def(12, "InvalidInstruction", "Invalid token instruction", "token")],
3764
+ [13, def(13, "InvalidState", "Invalid token account state", "token")],
3765
+ [14, def(14, "Overflow", "Arithmetic overflow in token operation", "token")],
3766
+ [15, def(15, "AuthorityTypeNotSupported", "Authority type not supported", "token")],
3767
+ [16, def(16, "MintCannotFreeze", "This mint cannot freeze accounts", "token")],
3768
+ [17, def(17, "AccountFrozen", "Account is frozen — cannot transfer", "token")],
3769
+ [6000, def(6000, "EmptyRoute", "No swap route found", "jupiter", false, "Token pair may not have liquidity. Try a different pair.")],
3770
+ [6001, def(6001, "SlippageToleranceExceeded", "Slippage tolerance exceeded — price moved during execution", "jupiter", true, "Retry or increase slippage tolerance")],
3771
+ [6002, def(6002, "InvalidCalculation", "Swap calculation error", "jupiter")],
3772
+ [6003, def(6003, "MissingPlatformFeeAccount", "Platform fee account not provided", "jupiter", false, "Server configuration issue — contact support")],
3773
+ [6004, def(6004, "InvalidSlippage", "Invalid slippage value", "jupiter")],
3774
+ [6005, def(6005, "NotEnoughPercent", "Split percent does not sum to 100", "jupiter")],
3775
+ [6006, def(6006, "InvalidInputIndex", "Invalid route input index", "jupiter")],
3776
+ [6007, def(6007, "InvalidOutputIndex", "Invalid route output index", "jupiter")],
3777
+ [6008, def(6008, "NotEnoughAccountKeys", "Not enough account keys for instruction", "jupiter")],
3778
+ [6009, def(6009, "NonZeroMinimumOutAmountNotSupported", "Non-zero minimum out amount not supported for this route", "jupiter")],
3779
+ [6010, def(6010, "InvalidRoutePlan", "Invalid route plan", "jupiter")],
3780
+ [6011, def(6011, "InvalidReferralAuthority", "Invalid referral authority", "jupiter")],
3781
+ [6012, def(6012, "LedgerTokenAccountDoesNotMatch", "Token ledger account mismatch", "jupiter")],
3782
+ [6013, def(6013, "InvalidTokenLedger", "Invalid token ledger state", "jupiter")],
3783
+ [6014, def(6014, "IncorrectTokenProgramID", "Incorrect token program ID", "jupiter")],
3784
+ [6015, def(6015, "TokenProgramNotProvided", "Token program not provided", "jupiter")],
3785
+ [6016, def(6016, "SwapNotSupported", "This swap is not supported", "jupiter")],
3786
+ [6017, def(6017, "ExactOutAmountNotMatched", "Exact output amount not met", "jupiter")],
3787
+ [6025, def(6025, "InvalidTokenAccount", "Invalid token account for platform fee", "jupiter", false, "Platform fee account may not be initialized — contact support")]
3788
+ ]);
3789
+ INSTRUCTION_ERRORS = new Map([
3790
+ ["InsufficientFunds", def(0, "InsufficientFunds", "Insufficient SOL for transaction fees", "system", false, "Fund your wallet with SOL for gas")],
3791
+ ["InvalidAccountData", def(0, "InvalidAccountData", "Account data is invalid or corrupt", "system")],
3792
+ ["AccountAlreadyInUse", def(0, "AccountAlreadyInUse", "Account is already in use", "system")],
3793
+ ["AccountNotFound", def(0, "AccountNotFound", "Account not found on chain", "system")],
3794
+ ["InvalidArgument", def(0, "InvalidArgument", "Invalid instruction argument", "system")],
3795
+ ["InvalidInstructionData", def(0, "InvalidInstructionData", "Invalid instruction data", "system")],
3796
+ ["InvalidAccountOwner", def(0, "InvalidAccountOwner", "Account is not owned by the expected program", "system")],
3797
+ ["ComputationalBudgetExceeded", def(0, "ComputationalBudgetExceeded", "Transaction exceeded compute budget", "compute-budget", true, "Retry — the transaction was too complex for the allocated compute units")],
3798
+ ["ProgramFailedToComplete", def(0, "ProgramFailedToComplete", "Program failed to complete", "system", true, "Retry — may be a transient issue")]
3799
+ ]);
3800
+ CUSTOM_ERROR_RE = /custom program error: 0x([0-9a-fA-F]+)/i;
3801
+ INSTRUCTION_INDEX_RE = /Error processing Instruction (\d+):/i;
3802
+ ANCHOR_ERROR_RE = /Error Number: (\d+)/i;
3803
+ KEYWORD_PATTERNS = [
3804
+ {
3805
+ test: (msg) => /insufficient\s*(funds|balance|lamports)/i.test(msg) || msg.toLowerCase().includes("insufficient balance"),
3806
+ classify: () => ({
3807
+ errorCode: "BAD_REQUEST",
3808
+ httpStatus: 400,
3809
+ message: "Insufficient balance to complete this trade",
3810
+ retryable: false,
3811
+ suggestion: "Check your wallet balance before trading",
3812
+ solanaError: "InsufficientFunds"
3813
+ })
3814
+ },
3815
+ {
3816
+ test: (msg) => msg.toLowerCase().includes("slippage"),
3817
+ classify: () => ({
3818
+ errorCode: "BAD_REQUEST",
3819
+ httpStatus: 400,
3820
+ message: "Slippage tolerance exceeded — price moved during execution",
3821
+ retryable: true,
3822
+ suggestion: "Retry or increase slippage tolerance",
3823
+ solanaError: "SlippageToleranceExceeded"
3824
+ })
3825
+ },
3826
+ {
3827
+ test: (msg) => {
3828
+ const lower = msg.toLowerCase();
3829
+ return lower.includes("expired") || lower.includes("blockhash not found") || lower.includes("block height exceeded");
3830
+ },
3831
+ classify: () => ({
3832
+ errorCode: "DEPENDENCY_ERROR",
3833
+ httpStatus: 502,
3834
+ message: "Transaction expired before confirmation",
3835
+ retryable: true,
3836
+ suggestion: "This is transient — retry with a fresh quote",
3837
+ solanaError: "TransactionExpired"
3838
+ })
3839
+ },
3840
+ {
3841
+ test: (msg) => msg.toLowerCase().includes("rate limit"),
3842
+ classify: (msg) => ({
3843
+ errorCode: "RATE_LIMITED",
3844
+ httpStatus: 429,
3845
+ message: msg,
3846
+ retryable: false,
3847
+ suggestion: "Wait a moment before retrying"
3848
+ })
3849
+ },
3850
+ {
3851
+ test: (msg) => {
3852
+ const lower = msg.toLowerCase();
3853
+ return lower.includes("unknown token") || lower.includes("token not found");
3854
+ },
3855
+ classify: (msg) => ({
3856
+ errorCode: "BAD_REQUEST",
3857
+ httpStatus: 400,
3858
+ message: msg,
3859
+ retryable: false,
3860
+ suggestion: "Use a known symbol (SOL, USDC, BONK, WIF) or pass a raw mint address"
3861
+ })
3862
+ }
3863
+ ];
3864
+ });
3865
+
3665
3866
  // src/lib/errors.ts
3666
3867
  import chalk from "chalk";
3667
3868
  function normalizeCliError(error) {
@@ -3690,43 +3891,12 @@ function printCliError(error) {
3690
3891
  }
3691
3892
  function mapTradeError(error) {
3692
3893
  const normalized = normalizeCliError(error);
3693
- const msg = normalized.message.toLowerCase();
3694
- if (msg.includes("slippage") || msg.includes("0x1789") || msg.includes("6025")) {
3695
- return {
3696
- message: "Slippage exceeded — price moved too much during execution",
3697
- suggestion: "Retry with higher slippage: --slippage 300",
3698
- retryable: true
3699
- };
3700
- }
3701
- if (msg.includes("expired") || msg.includes("blockhash")) {
3702
- return {
3703
- message: "Transaction expired — took too long to confirm",
3704
- suggestion: "This is transient. Try again.",
3705
- retryable: true
3706
- };
3707
- }
3708
- if (msg.includes("insufficient balance") || msg.includes("insufficient funds") || msg.includes("0x1")) {
3709
- return {
3710
- message: "Insufficient balance",
3711
- suggestion: "Check your balance with: cabal-cli status",
3712
- retryable: false
3713
- };
3714
- }
3715
- if (msg.includes("rate limit")) {
3716
- return {
3717
- message: normalized.message,
3718
- suggestion: "Wait a moment before retrying.",
3719
- retryable: false
3720
- };
3721
- }
3722
- if (msg.includes("unknown token") || msg.includes("token not found")) {
3723
- return {
3724
- message: normalized.message,
3725
- suggestion: "Use a known symbol (SOL, USDC, BONK, WIF) or pass a raw mint address.",
3726
- retryable: false
3727
- };
3728
- }
3729
- return { message: normalized.message, retryable: false };
3894
+ const classified = classifyTradeError(normalized.message);
3895
+ return {
3896
+ message: classified.message,
3897
+ suggestion: classified.suggestion,
3898
+ retryable: classified.retryable
3899
+ };
3730
3900
  }
3731
3901
  function printTradeError(error) {
3732
3902
  const mapped = mapTradeError(error);
@@ -3748,8 +3918,9 @@ function toStructuredError(error) {
3748
3918
  }
3749
3919
  };
3750
3920
  }
3751
- var init_errors2 = __esm(() => {
3921
+ var init_errors3 = __esm(() => {
3752
3922
  init_src();
3923
+ init_errors2();
3753
3924
  });
3754
3925
 
3755
3926
  // src/mcp/server.ts
@@ -3799,7 +3970,7 @@ async function createServer() {
3799
3970
  size: z22.number().optional().describe("Hyperliquid: position size"),
3800
3971
  orderType: z22.enum(["market", "limit"]).optional().describe("Hyperliquid: order type (default: market)"),
3801
3972
  price: z22.number().optional().describe("Hyperliquid: limit price (required for limit orders)"),
3802
- model: modelSchema.optional().describe("AI model name for attribution")
3973
+ model: z22.string().optional().describe("AI model name for attribution")
3803
3974
  };
3804
3975
  server.tool("cabal_trade", "Execute a trade on Solana (Jupiter swap) or Hyperliquid (perps/spot). Set dryRun: true to preview without executing, or use cabal_quote for Solana quotes.", tradeSchema, async (params) => {
3805
3976
  if (params.chain === "solana") {
@@ -4017,7 +4188,7 @@ Describe: (1) what triggers it, (2) how it unfolds, (3) what it looks like after
4017
4188
  var init_server = __esm(() => {
4018
4189
  init_src();
4019
4190
  init_env();
4020
- init_errors2();
4191
+ init_errors3();
4021
4192
  });
4022
4193
 
4023
4194
  // src/mcp-server.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cabaltrading/cli",
3
- "version": "0.4.4",
3
+ "version": "0.4.5",
4
4
  "description": "CLI for Cabal - connect your AI agent and start trading.",
5
5
  "keywords": [
6
6
  "cabal",