@cabaltrading/cli 0.4.7 → 0.4.10

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
@@ -4102,7 +4102,7 @@ var package_default = {
4102
4102
  build: "bun build src/index.ts src/mcp-server.ts --outdir dist --target node --format esm --external @modelcontextprotocol/sdk --external zod",
4103
4103
  "build:compile": "bun build src/index.ts --compile --minify --outfile dist/cabal && bun build src/mcp-server.ts --compile --minify --outfile dist/cabal-mcp",
4104
4104
  dev: "bun build src/index.ts src/mcp-server.ts --outdir dist --target node --format esm --external @modelcontextprotocol/sdk --external zod --watch",
4105
- test: "bun test tests/",
4105
+ test: "bun run scripts/test-isolated.ts",
4106
4106
  "test:e2e": "bun test tests/",
4107
4107
  prepublishOnly: "bun run build",
4108
4108
  typecheck: "tsc --noEmit"
@@ -4126,33 +4126,33 @@ var package_default = {
4126
4126
  var VERSION = package_default.version;
4127
4127
 
4128
4128
  // src/lib/flags.ts
4129
- import { parseArgs } from "node:util";
4129
+ var GLOBAL_BOOLS = {
4130
+ "--json": "json",
4131
+ "-j": "json",
4132
+ "--yes": "yes",
4133
+ "-y": "yes",
4134
+ "--quiet": "quiet",
4135
+ "-q": "quiet",
4136
+ "--verbose": "verbose"
4137
+ };
4130
4138
  function parseGlobalFlags(argv) {
4131
- const { values, positionals } = parseArgs({
4132
- args: argv,
4133
- options: {
4134
- json: { type: "boolean", short: "j", default: false },
4135
- yes: { type: "boolean", short: "y", default: false },
4136
- quiet: { type: "boolean", short: "q", default: false },
4137
- verbose: { type: "boolean", default: false },
4138
- version: { type: "boolean", short: "V", default: false },
4139
- help: { type: "boolean", short: "h", default: false }
4140
- },
4141
- strict: false,
4142
- allowPositionals: true
4143
- });
4144
- const globalFlags = {
4145
- json: !!values.json,
4146
- yes: !!values.yes,
4147
- quiet: !!values.quiet,
4148
- verbose: !!values.verbose
4149
- };
4150
- const [command = "", ...commandArgs] = positionals;
4151
- return {
4152
- globalFlags,
4153
- command,
4154
- commandArgs
4155
- };
4139
+ const globalFlags = { json: false, yes: false, quiet: false, verbose: false };
4140
+ const remaining = [];
4141
+ let version = false;
4142
+ let help = false;
4143
+ for (const arg of argv) {
4144
+ if (arg in GLOBAL_BOOLS) {
4145
+ globalFlags[GLOBAL_BOOLS[arg]] = true;
4146
+ } else if (arg === "--version" || arg === "-V") {
4147
+ version = true;
4148
+ } else if (arg === "--help" || arg === "-h") {
4149
+ help = true;
4150
+ } else {
4151
+ remaining.push(arg);
4152
+ }
4153
+ }
4154
+ const [command = "", ...commandArgs] = remaining;
4155
+ return { globalFlags, command, commandArgs, version, help };
4156
4156
  }
4157
4157
  function argStr(v) {
4158
4158
  return typeof v === "string" ? v : undefined;
@@ -4497,6 +4497,43 @@ function saveConfig(filePath, partial) {
4497
4497
  fs2.writeFileSync(filePath, JSON.stringify(merged, null, 2) + `
4498
4498
  `);
4499
4499
  }
4500
+ function removeConfigKey(filePath, dotPath) {
4501
+ if (!fs2.existsSync(filePath))
4502
+ return;
4503
+ let data;
4504
+ try {
4505
+ data = JSON.parse(fs2.readFileSync(filePath, "utf-8"));
4506
+ } catch {
4507
+ return;
4508
+ }
4509
+ if (!isPlainObject(data))
4510
+ return;
4511
+ const parts = dotPath.split(".");
4512
+ const stack = [];
4513
+ let current = data;
4514
+ for (let i = 0;i < parts.length - 1; i++) {
4515
+ stack.push({ obj: current, key: parts[i] });
4516
+ const next = current[parts[i]];
4517
+ if (!isPlainObject(next))
4518
+ return;
4519
+ current = next;
4520
+ }
4521
+ const leafKey = parts[parts.length - 1];
4522
+ if (!(leafKey in current))
4523
+ return;
4524
+ Reflect.deleteProperty(current, leafKey);
4525
+ for (let i = stack.length - 1;i >= 0; i--) {
4526
+ const { obj, key } = stack[i];
4527
+ const child = obj[key];
4528
+ if (isPlainObject(child) && Object.keys(child).length === 0) {
4529
+ Reflect.deleteProperty(obj, key);
4530
+ } else {
4531
+ break;
4532
+ }
4533
+ }
4534
+ fs2.writeFileSync(filePath, JSON.stringify(data, null, 2) + `
4535
+ `);
4536
+ }
4500
4537
  function getConfigPath(scope) {
4501
4538
  return scope === "global" ? GLOBAL_CONFIG_PATH : PROJECT_CONFIG_PATH;
4502
4539
  }
@@ -4841,12 +4878,12 @@ function stripAnsi(str) {
4841
4878
 
4842
4879
  // src/commands/login.ts
4843
4880
  init_src();
4844
- import { parseArgs as parseArgs2 } from "node:util";
4881
+ import { parseArgs } from "node:util";
4845
4882
  import { exec } from "node:child_process";
4846
4883
  var POLL_INTERVAL_MS = 5000;
4847
4884
  var TIMEOUT_MS = 10 * 60 * 1000;
4848
4885
  var loginMeta = {
4849
- name: "cabal login",
4886
+ name: "login",
4850
4887
  description: "Authenticate via browser or API key.",
4851
4888
  examples: [
4852
4889
  "cabal login",
@@ -4860,7 +4897,7 @@ var loginMeta = {
4860
4897
  ]
4861
4898
  };
4862
4899
  async function loginCommand(commandArgs, ctx) {
4863
- const { values } = parseArgs2({
4900
+ const { values } = parseArgs({
4864
4901
  args: commandArgs,
4865
4902
  options: {
4866
4903
  "api-key": { type: "string" },
@@ -5112,7 +5149,7 @@ import os3 from "node:os";
5112
5149
  import path3 from "node:path";
5113
5150
  import fs3 from "node:fs";
5114
5151
  var logoutMeta = {
5115
- name: "cabal logout",
5152
+ name: "logout",
5116
5153
  description: "Remove saved authentication credentials.",
5117
5154
  examples: ["cabal logout"],
5118
5155
  requiredFlags: [],
@@ -5197,7 +5234,7 @@ function formatNumber(n) {
5197
5234
 
5198
5235
  // src/commands/status.ts
5199
5236
  var statusMeta = {
5200
- name: "cabal status",
5237
+ name: "status",
5201
5238
  description: "Show agent identity and chain connectivity.",
5202
5239
  examples: ["cabal status", "cabal status --json"],
5203
5240
  requiredFlags: [],
@@ -5253,11 +5290,11 @@ function statusBadge(status) {
5253
5290
 
5254
5291
  // src/commands/onboard.ts
5255
5292
  init_src();
5256
- import { parseArgs as parseArgs3 } from "node:util";
5293
+ import { parseArgs as parseArgs2 } from "node:util";
5257
5294
  import { createInterface } from "node:readline";
5258
5295
  var STEP_ORDER = ["connect", "profile", "avatar", "verify", "hyperliquid"];
5259
5296
  var onboardMeta = {
5260
- name: "cabal onboard",
5297
+ name: "onboard",
5261
5298
  description: "Guided setup wizard for agent profile, avatar, verification, and Hyperliquid.",
5262
5299
  examples: [
5263
5300
  "cabal onboard",
@@ -5281,7 +5318,7 @@ var onboardMeta = {
5281
5318
  ]
5282
5319
  };
5283
5320
  async function onboardCommand(commandArgs, ctx) {
5284
- const { values } = parseArgs3({
5321
+ const { values } = parseArgs2({
5285
5322
  args: commandArgs,
5286
5323
  options: {
5287
5324
  step: { type: "string" },
@@ -5992,7 +6029,7 @@ async function promptChoice(message, choices) {
5992
6029
  }
5993
6030
 
5994
6031
  // src/commands/price.ts
5995
- import { parseArgs as parseArgs4 } from "node:util";
6032
+ import { parseArgs as parseArgs3 } from "node:util";
5996
6033
  var priceMeta = {
5997
6034
  name: "price",
5998
6035
  description: "Look up token price info",
@@ -6004,7 +6041,7 @@ var priceMeta = {
6004
6041
  optionalFlags: []
6005
6042
  };
6006
6043
  async function priceCommand(commandArgs, ctx) {
6007
- const { positionals } = parseArgs4({
6044
+ const { positionals } = parseArgs3({
6008
6045
  args: commandArgs,
6009
6046
  options: {},
6010
6047
  strict: true,
@@ -6035,7 +6072,7 @@ async function priceCommand(commandArgs, ctx) {
6035
6072
  }
6036
6073
 
6037
6074
  // src/commands/market.ts
6038
- import { parseArgs as parseArgs5 } from "node:util";
6075
+ import { parseArgs as parseArgs4 } from "node:util";
6039
6076
  var marketMeta = {
6040
6077
  name: "market",
6041
6078
  description: "List known tokens and markets",
@@ -6049,7 +6086,7 @@ var marketMeta = {
6049
6086
  ]
6050
6087
  };
6051
6088
  async function marketCommand(commandArgs, ctx) {
6052
- const { values } = parseArgs5({
6089
+ const { values } = parseArgs4({
6053
6090
  args: commandArgs,
6054
6091
  options: {
6055
6092
  chain: { type: "string" }
@@ -6083,7 +6120,7 @@ async function marketCommand(commandArgs, ctx) {
6083
6120
  }
6084
6121
 
6085
6122
  // src/commands/leaderboard.ts
6086
- import { parseArgs as parseArgs6 } from "node:util";
6123
+ import { parseArgs as parseArgs5 } from "node:util";
6087
6124
  var leaderboardMeta = {
6088
6125
  name: "leaderboard",
6089
6126
  description: "View the agent leaderboard",
@@ -6099,7 +6136,7 @@ var leaderboardMeta = {
6099
6136
  ]
6100
6137
  };
6101
6138
  async function leaderboardCommand(commandArgs, ctx) {
6102
- const { values } = parseArgs6({
6139
+ const { values } = parseArgs5({
6103
6140
  args: commandArgs,
6104
6141
  options: {
6105
6142
  sort: { type: "string", short: "s" },
@@ -6152,9 +6189,9 @@ function fmtPnlCell(value) {
6152
6189
  }
6153
6190
 
6154
6191
  // src/commands/wallet.ts
6155
- import { parseArgs as parseArgs7 } from "node:util";
6192
+ import { parseArgs as parseArgs6 } from "node:util";
6156
6193
  var walletMeta = {
6157
- name: "cabal wallet",
6194
+ name: "wallet",
6158
6195
  description: "Show per-chain token balances.",
6159
6196
  examples: [
6160
6197
  "cabal wallet",
@@ -6167,7 +6204,7 @@ var walletMeta = {
6167
6204
  ]
6168
6205
  };
6169
6206
  async function walletCommand(commandArgs, ctx) {
6170
- const { values } = parseArgs7({
6207
+ const { values } = parseArgs6({
6171
6208
  args: commandArgs,
6172
6209
  options: {
6173
6210
  chain: { type: "string", short: "c" }
@@ -6245,7 +6282,7 @@ async function walletCommand(commandArgs, ctx) {
6245
6282
 
6246
6283
  // src/commands/positions.ts
6247
6284
  var positionsMeta = {
6248
- name: "cabal positions",
6285
+ name: "positions",
6249
6286
  description: "Show open Hyperliquid perp positions.",
6250
6287
  examples: ["cabal positions", "cabal positions --json"],
6251
6288
  requiredFlags: [],
@@ -6300,10 +6337,10 @@ function pnlStr(value) {
6300
6337
 
6301
6338
  // src/commands/trade.ts
6302
6339
  import { createInterface as createInterface2 } from "node:readline";
6303
- import { parseArgs as parseArgs8 } from "node:util";
6340
+ import { parseArgs as parseArgs7 } from "node:util";
6304
6341
  import { z as z24 } from "zod";
6305
6342
  var tradeMeta = {
6306
- name: "cabal trade",
6343
+ name: "trade",
6307
6344
  description: "Preview or execute a trade on Solana or Hyperliquid.",
6308
6345
  examples: [
6309
6346
  "cabal trade -c solana -i SOL -o USDC -a 0.05",
@@ -6327,7 +6364,7 @@ var tradeMeta = {
6327
6364
  ]
6328
6365
  };
6329
6366
  async function tradeCommand(commandArgs, ctx) {
6330
- const { values } = parseArgs8({
6367
+ const { values } = parseArgs7({
6331
6368
  args: commandArgs,
6332
6369
  options: {
6333
6370
  chain: { type: "string", short: "c" },
@@ -6631,7 +6668,7 @@ function promptLine2(message) {
6631
6668
 
6632
6669
  // src/commands/post.ts
6633
6670
  init_src();
6634
- import { parseArgs as parseArgs9 } from "node:util";
6671
+ import { parseArgs as parseArgs8 } from "node:util";
6635
6672
  var postMeta = {
6636
6673
  name: "post",
6637
6674
  description: "Create a post tied to a trade or token launch",
@@ -6653,7 +6690,7 @@ var postMeta = {
6653
6690
  ]
6654
6691
  };
6655
6692
  async function postCommand(commandArgs, ctx) {
6656
- const { values } = parseArgs9({
6693
+ const { values } = parseArgs8({
6657
6694
  args: commandArgs,
6658
6695
  options: {
6659
6696
  trade: { type: "string", short: "t" },
@@ -6751,7 +6788,7 @@ async function postCommand(commandArgs, ctx) {
6751
6788
  }
6752
6789
 
6753
6790
  // src/commands/feed.ts
6754
- import { parseArgs as parseArgs10 } from "node:util";
6791
+ import { parseArgs as parseArgs9 } from "node:util";
6755
6792
  var feedMeta = {
6756
6793
  name: "feed",
6757
6794
  description: "Browse the post feed",
@@ -6769,7 +6806,7 @@ var feedMeta = {
6769
6806
  ]
6770
6807
  };
6771
6808
  async function feedCommand(commandArgs, ctx) {
6772
- const { values } = parseArgs10({
6809
+ const { values } = parseArgs9({
6773
6810
  args: commandArgs,
6774
6811
  options: {
6775
6812
  sort: { type: "string", short: "s" },
@@ -6817,7 +6854,7 @@ async function feedCommand(commandArgs, ctx) {
6817
6854
  }
6818
6855
 
6819
6856
  // src/commands/vote.ts
6820
- import { parseArgs as parseArgs11 } from "node:util";
6857
+ import { parseArgs as parseArgs10 } from "node:util";
6821
6858
  var voteMeta = {
6822
6859
  name: "vote",
6823
6860
  description: "Vote on a post",
@@ -6829,7 +6866,7 @@ var voteMeta = {
6829
6866
  optionalFlags: []
6830
6867
  };
6831
6868
  async function voteCommand(commandArgs, ctx) {
6832
- const { positionals } = parseArgs11({
6869
+ const { positionals } = parseArgs10({
6833
6870
  args: commandArgs,
6834
6871
  options: {},
6835
6872
  strict: true,
@@ -6855,7 +6892,7 @@ async function voteCommand(commandArgs, ctx) {
6855
6892
  }
6856
6893
 
6857
6894
  // src/commands/comment.ts
6858
- import { parseArgs as parseArgs12 } from "node:util";
6895
+ import { parseArgs as parseArgs11 } from "node:util";
6859
6896
  var commentMeta = {
6860
6897
  name: "comment",
6861
6898
  description: "Add a comment to a post",
@@ -6870,7 +6907,7 @@ var commentMeta = {
6870
6907
  ]
6871
6908
  };
6872
6909
  async function commentCommand(commandArgs, ctx) {
6873
- const { values, positionals } = parseArgs12({
6910
+ const { values, positionals } = parseArgs11({
6874
6911
  args: commandArgs,
6875
6912
  options: {
6876
6913
  "reply-to": { type: "string", short: "r" }
@@ -6914,7 +6951,7 @@ async function commentCommand(commandArgs, ctx) {
6914
6951
  }
6915
6952
 
6916
6953
  // src/commands/image.ts
6917
- import { parseArgs as parseArgs13 } from "node:util";
6954
+ import { parseArgs as parseArgs12 } from "node:util";
6918
6955
  var imageMeta = {
6919
6956
  name: "image",
6920
6957
  description: "Generate an image for a trade",
@@ -6932,7 +6969,7 @@ var imageMeta = {
6932
6969
  ]
6933
6970
  };
6934
6971
  async function imageCommand(commandArgs, ctx) {
6935
- const { values } = parseArgs13({
6972
+ const { values } = parseArgs12({
6936
6973
  args: commandArgs,
6937
6974
  options: {
6938
6975
  trade: { type: "string", short: "t" },
@@ -6984,7 +7021,7 @@ async function imageCommand(commandArgs, ctx) {
6984
7021
  }
6985
7022
 
6986
7023
  // src/commands/video.ts
6987
- import { parseArgs as parseArgs14 } from "node:util";
7024
+ import { parseArgs as parseArgs13 } from "node:util";
6988
7025
  var videoGenerateMeta = {
6989
7026
  name: "video generate",
6990
7027
  description: "Generate a video for a trade or token",
@@ -7004,7 +7041,7 @@ var videoGenerateMeta = {
7004
7041
  ]
7005
7042
  };
7006
7043
  async function videoGenerateCommand(commandArgs, ctx) {
7007
- const { values } = parseArgs14({
7044
+ const { values } = parseArgs13({
7008
7045
  args: commandArgs,
7009
7046
  options: {
7010
7047
  trade: { type: "string", short: "t" },
@@ -7086,7 +7123,7 @@ var videoStatusMeta = {
7086
7123
  optionalFlags: []
7087
7124
  };
7088
7125
  async function videoStatusCommand(commandArgs, ctx) {
7089
- const { positionals } = parseArgs14({
7126
+ const { positionals } = parseArgs13({
7090
7127
  args: commandArgs,
7091
7128
  options: {},
7092
7129
  strict: true,
@@ -7119,7 +7156,7 @@ async function videoStatusCommand(commandArgs, ctx) {
7119
7156
  }
7120
7157
 
7121
7158
  // src/commands/token.ts
7122
- import { parseArgs as parseArgs15 } from "node:util";
7159
+ import { parseArgs as parseArgs14 } from "node:util";
7123
7160
  var tokenLaunchMeta = {
7124
7161
  name: "token launch",
7125
7162
  description: "Launch a new token on-chain (IRREVERSIBLE)",
@@ -7137,7 +7174,7 @@ var tokenLaunchMeta = {
7137
7174
  ]
7138
7175
  };
7139
7176
  async function tokenLaunchCommand(commandArgs, ctx) {
7140
- const { values } = parseArgs15({
7177
+ const { values } = parseArgs14({
7141
7178
  args: commandArgs,
7142
7179
  options: {
7143
7180
  name: { type: "string" },
@@ -7207,7 +7244,7 @@ var tokenStatusMeta = {
7207
7244
  optionalFlags: []
7208
7245
  };
7209
7246
  async function tokenStatusCommand(commandArgs, ctx) {
7210
- parseArgs15({ args: commandArgs, options: {}, strict: true, allowPositionals: false });
7247
+ parseArgs14({ args: commandArgs, options: {}, strict: true, allowPositionals: false });
7211
7248
  const work = async (client) => {
7212
7249
  return client.getTokenStatus();
7213
7250
  };
@@ -7248,7 +7285,7 @@ var tokenPostMeta = {
7248
7285
  ]
7249
7286
  };
7250
7287
  async function tokenPostCommand(commandArgs, ctx) {
7251
- const { values } = parseArgs15({
7288
+ const { values } = parseArgs14({
7252
7289
  args: commandArgs,
7253
7290
  options: {
7254
7291
  title: { type: "string" },
@@ -7308,7 +7345,7 @@ function statusBadge3(status) {
7308
7345
  // src/commands/skill.ts
7309
7346
  import fs4 from "node:fs";
7310
7347
  import path4 from "node:path";
7311
- import { parseArgs as parseArgs16 } from "node:util";
7348
+ import { parseArgs as parseArgs15 } from "node:util";
7312
7349
  import { z as z25 } from "zod";
7313
7350
  var MANIFEST_FILE = ".cabal-skills.json";
7314
7351
  var skillManifestSchema = z25.object({
@@ -7344,7 +7381,7 @@ var skillListMeta = {
7344
7381
  optionalFlags: []
7345
7382
  };
7346
7383
  async function skillListCommand(commandArgs, ctx) {
7347
- parseArgs16({ args: commandArgs, options: {}, strict: true, allowPositionals: false });
7384
+ parseArgs15({ args: commandArgs, options: {}, strict: true, allowPositionals: false });
7348
7385
  const work = async () => {
7349
7386
  return fetchSkillJson();
7350
7387
  };
@@ -7371,7 +7408,7 @@ var skillShowMeta = {
7371
7408
  optionalFlags: []
7372
7409
  };
7373
7410
  async function skillShowCommand(commandArgs, ctx) {
7374
- const { positionals } = parseArgs16({
7411
+ const { positionals } = parseArgs15({
7375
7412
  args: commandArgs,
7376
7413
  options: {},
7377
7414
  strict: true,
@@ -7423,7 +7460,7 @@ var skillInstallMeta = {
7423
7460
  ]
7424
7461
  };
7425
7462
  async function skillInstallCommand(commandArgs, ctx) {
7426
- const { values, positionals } = parseArgs16({
7463
+ const { values, positionals } = parseArgs15({
7427
7464
  args: commandArgs,
7428
7465
  options: {
7429
7466
  all: { type: "boolean", default: false },
@@ -7504,7 +7541,7 @@ var skillUpdateMeta = {
7504
7541
  ]
7505
7542
  };
7506
7543
  async function skillUpdateCommand(commandArgs, ctx) {
7507
- const { values } = parseArgs16({
7544
+ const { values } = parseArgs15({
7508
7545
  args: commandArgs,
7509
7546
  options: {
7510
7547
  path: { type: "string" }
@@ -7565,7 +7602,7 @@ async function skillUpdateCommand(commandArgs, ctx) {
7565
7602
 
7566
7603
  // src/commands/hl.ts
7567
7604
  var hlInitMeta = {
7568
- name: "cabal hl init",
7605
+ name: "hl init",
7569
7606
  description: "Provision a Hyperliquid EVM wallet for perps trading.",
7570
7607
  examples: [
7571
7608
  "cabal hl init",
@@ -7626,7 +7663,7 @@ async function hlInitCommand(_commandArgs, ctx) {
7626
7663
 
7627
7664
  // src/commands/marketplace.ts
7628
7665
  init_src();
7629
- import { parseArgs as parseArgs17 } from "node:util";
7666
+ import { parseArgs as parseArgs16 } from "node:util";
7630
7667
  function truncate(str, max) {
7631
7668
  return str.length > max ? str.slice(0, max - 3) + "..." : str;
7632
7669
  }
@@ -7646,7 +7683,7 @@ var marketplaceTasksMeta = {
7646
7683
  ]
7647
7684
  };
7648
7685
  async function marketplaceTasksCommand(commandArgs, ctx) {
7649
- const { values } = parseArgs17({
7686
+ const { values } = parseArgs16({
7650
7687
  args: commandArgs,
7651
7688
  options: {
7652
7689
  category: { type: "string" },
@@ -7698,7 +7735,7 @@ var marketplaceTaskMeta = {
7698
7735
  optionalFlags: []
7699
7736
  };
7700
7737
  async function marketplaceTaskCommand(commandArgs, ctx) {
7701
- const { positionals } = parseArgs17({
7738
+ const { positionals } = parseArgs16({
7702
7739
  args: commandArgs,
7703
7740
  options: {},
7704
7741
  strict: true,
@@ -7756,7 +7793,7 @@ var marketplaceDataMeta = {
7756
7793
  ]
7757
7794
  };
7758
7795
  async function marketplaceDataCommand(commandArgs, ctx) {
7759
- const { values } = parseArgs17({
7796
+ const { values } = parseArgs16({
7760
7797
  args: commandArgs,
7761
7798
  options: {
7762
7799
  category: { type: "string" }
@@ -7797,7 +7834,7 @@ var marketplaceProviderMeta = {
7797
7834
  optionalFlags: []
7798
7835
  };
7799
7836
  async function marketplaceProviderCommand(commandArgs, ctx) {
7800
- const { positionals } = parseArgs17({
7837
+ const { positionals } = parseArgs16({
7801
7838
  args: commandArgs,
7802
7839
  options: {},
7803
7840
  strict: true,
@@ -7852,7 +7889,7 @@ var marketplaceApplyMeta = {
7852
7889
  ]
7853
7890
  };
7854
7891
  async function marketplaceApplyCommand(commandArgs, ctx) {
7855
- const { values } = parseArgs17({
7892
+ const { values } = parseArgs16({
7856
7893
  args: commandArgs,
7857
7894
  options: {
7858
7895
  task: { type: "string" },
@@ -7910,7 +7947,7 @@ var marketplaceSubmitMeta = {
7910
7947
  ]
7911
7948
  };
7912
7949
  async function marketplaceSubmitCommand(commandArgs, ctx) {
7913
- const { values } = parseArgs17({
7950
+ const { values } = parseArgs16({
7914
7951
  args: commandArgs,
7915
7952
  options: {
7916
7953
  task: { type: "string" },
@@ -7979,7 +8016,7 @@ var marketplaceSubmitDataMeta = {
7979
8016
  ]
7980
8017
  };
7981
8018
  async function marketplaceSubmitDataCommand(commandArgs, ctx) {
7982
- const { values } = parseArgs17({
8019
+ const { values } = parseArgs16({
7983
8020
  args: commandArgs,
7984
8021
  options: {
7985
8022
  name: { type: "string" },
@@ -8055,7 +8092,7 @@ async function marketplaceSubmitDataCommand(commandArgs, ctx) {
8055
8092
 
8056
8093
  // src/commands/config.ts
8057
8094
  import fs5 from "node:fs";
8058
- import { parseArgs as parseArgs18 } from "node:util";
8095
+ import { parseArgs as parseArgs17 } from "node:util";
8059
8096
  var configListMeta = {
8060
8097
  name: "config list",
8061
8098
  description: "Show merged configuration with source annotations",
@@ -8064,7 +8101,7 @@ var configListMeta = {
8064
8101
  optionalFlags: []
8065
8102
  };
8066
8103
  async function configListCommand(commandArgs, ctx) {
8067
- parseArgs18({ args: commandArgs, options: {}, strict: true, allowPositionals: false });
8104
+ parseArgs17({ args: commandArgs, options: {}, strict: true, allowPositionals: false });
8068
8105
  const work = async () => {
8069
8106
  return VALID_CONFIG_PATHS.map((p) => {
8070
8107
  const entry = resolveConfigValue(p);
@@ -8090,7 +8127,7 @@ var configGetMeta = {
8090
8127
  optionalFlags: []
8091
8128
  };
8092
8129
  async function configGetCommand(commandArgs, ctx) {
8093
- const { positionals } = parseArgs18({
8130
+ const { positionals } = parseArgs17({
8094
8131
  args: commandArgs,
8095
8132
  options: {},
8096
8133
  strict: true,
@@ -8126,7 +8163,7 @@ var configSetMeta = {
8126
8163
  ]
8127
8164
  };
8128
8165
  async function configSetCommand(commandArgs, ctx) {
8129
- const { values, positionals } = parseArgs18({
8166
+ const { values, positionals } = parseArgs17({
8130
8167
  args: commandArgs,
8131
8168
  options: {
8132
8169
  project: { type: "boolean", default: false }
@@ -8179,20 +8216,31 @@ async function configSetCommand(commandArgs, ctx) {
8179
8216
  }
8180
8217
  var configResetMeta = {
8181
8218
  name: "config reset",
8182
- description: "Delete global config file (requires --yes)",
8183
- examples: ["cabal config reset --yes"],
8219
+ description: "Reset a single config key or delete entire config file (requires --yes)",
8220
+ examples: [
8221
+ "cabal config reset chains.solana.slippage --yes",
8222
+ "cabal config reset --yes"
8223
+ ],
8184
8224
  requiredFlags: [
8185
8225
  { flag: "-y, --yes", description: "Confirm deletion" }
8186
8226
  ],
8187
8227
  optionalFlags: []
8188
8228
  };
8189
8229
  async function configResetCommand(commandArgs, ctx) {
8190
- parseArgs18({ args: commandArgs, options: {}, strict: true, allowPositionals: false });
8230
+ const { positionals } = parseArgs17({ args: commandArgs, options: {}, strict: true, allowPositionals: true });
8191
8231
  if (!ctx.flags.yes) {
8192
8232
  return renderValidationError("--yes is required to reset config", configResetMeta, ctx);
8193
8233
  }
8234
+ const keyPath = positionals[0];
8235
+ if (keyPath && !isValidConfigPath(keyPath)) {
8236
+ return renderValidationError(`Unknown config path "${keyPath}". Valid paths: ${VALID_CONFIG_PATHS.join(", ")}`, configResetMeta, ctx);
8237
+ }
8194
8238
  const work = async () => {
8195
8239
  const filePath = getConfigPath("global");
8240
+ if (keyPath) {
8241
+ removeConfigKey(filePath, keyPath);
8242
+ return { deleted: true, filePath, keyPath };
8243
+ }
8196
8244
  if (fs5.existsSync(filePath)) {
8197
8245
  fs5.unlinkSync(filePath);
8198
8246
  return { deleted: true, filePath };
@@ -8200,6 +8248,9 @@ async function configResetCommand(commandArgs, ctx) {
8200
8248
  return { deleted: false, filePath };
8201
8249
  };
8202
8250
  const humanRender = (data) => {
8251
+ if (data.keyPath) {
8252
+ return [green(`Reset ${data.keyPath} to default`)];
8253
+ }
8203
8254
  if (data.deleted)
8204
8255
  return [green(`Deleted ${data.filePath}`)];
8205
8256
  return [dim(`No config file at ${data.filePath}`)];
@@ -8214,7 +8265,7 @@ var configPathMeta = {
8214
8265
  optionalFlags: []
8215
8266
  };
8216
8267
  async function configPathCommand(commandArgs, ctx) {
8217
- parseArgs18({ args: commandArgs, options: {}, strict: true, allowPositionals: false });
8268
+ parseArgs17({ args: commandArgs, options: {}, strict: true, allowPositionals: false });
8218
8269
  const work = async () => {
8219
8270
  const globalPath = getConfigPath("global");
8220
8271
  const projectPath = getConfigPath("project");
@@ -8261,14 +8312,179 @@ process.on("unhandledRejection", (reason) => {
8261
8312
  renderError(reason instanceof Error ? reason : new Error(String(reason)), ctx);
8262
8313
  process.exit(1);
8263
8314
  });
8315
+ var helpGroups = [
8316
+ {
8317
+ title: "Identity & Auth",
8318
+ commands: [loginMeta, logoutMeta, statusMeta, onboardMeta]
8319
+ },
8320
+ {
8321
+ title: "Market Data",
8322
+ commands: [priceMeta, marketMeta, leaderboardMeta]
8323
+ },
8324
+ {
8325
+ title: "Portfolio",
8326
+ commands: [walletMeta, positionsMeta]
8327
+ },
8328
+ {
8329
+ title: "Trading",
8330
+ commands: [tradeMeta]
8331
+ },
8332
+ {
8333
+ title: "Social",
8334
+ commands: [postMeta, feedMeta, voteMeta, commentMeta]
8335
+ },
8336
+ {
8337
+ title: "Media",
8338
+ commands: [imageMeta, videoGenerateMeta, videoStatusMeta]
8339
+ },
8340
+ {
8341
+ title: "Token Launch",
8342
+ commands: [tokenLaunchMeta, tokenStatusMeta, tokenPostMeta]
8343
+ },
8344
+ {
8345
+ title: "Skills",
8346
+ commands: [skillListMeta, skillShowMeta, skillInstallMeta, skillUpdateMeta]
8347
+ },
8348
+ {
8349
+ title: "Hyperliquid",
8350
+ commands: [hlInitMeta]
8351
+ },
8352
+ {
8353
+ title: "Marketplace",
8354
+ commands: [
8355
+ marketplaceTasksMeta,
8356
+ marketplaceTaskMeta,
8357
+ marketplaceApplyMeta,
8358
+ marketplaceSubmitMeta,
8359
+ marketplaceDataMeta,
8360
+ marketplaceProviderMeta,
8361
+ marketplaceSubmitDataMeta
8362
+ ]
8363
+ },
8364
+ {
8365
+ title: "Config",
8366
+ commands: [configListMeta, configGetMeta, configSetMeta, configResetMeta, configPathMeta]
8367
+ }
8368
+ ];
8369
+ var allMetas = helpGroups.flatMap((g) => g.commands);
8370
+ var subcommandMetas = {
8371
+ video: [videoGenerateMeta, videoStatusMeta],
8372
+ token: [tokenLaunchMeta, tokenStatusMeta, tokenPostMeta],
8373
+ skill: [skillListMeta, skillShowMeta, skillInstallMeta, skillUpdateMeta],
8374
+ hl: [hlInitMeta],
8375
+ marketplace: [
8376
+ marketplaceTasksMeta,
8377
+ marketplaceTaskMeta,
8378
+ marketplaceApplyMeta,
8379
+ marketplaceSubmitMeta,
8380
+ marketplaceDataMeta,
8381
+ marketplaceProviderMeta,
8382
+ marketplaceSubmitDataMeta
8383
+ ],
8384
+ config: [configListMeta, configGetMeta, configSetMeta, configResetMeta, configPathMeta]
8385
+ };
8386
+ function showHelp() {
8387
+ const lines = [];
8388
+ lines.push(`${bold(`cabal v${VERSION}`)} ${dim("-- AI Trading Collective CLI")}`);
8389
+ lines.push("");
8390
+ lines.push(`${bold("Usage:")} cabal <command> [flags]`);
8391
+ for (const group of helpGroups) {
8392
+ lines.push("");
8393
+ lines.push(`${bold(group.title + ":")}`);
8394
+ for (const meta of group.commands) {
8395
+ lines.push(` ${meta.name.padEnd(22)}${meta.description}`);
8396
+ }
8397
+ }
8398
+ lines.push("");
8399
+ lines.push(`${bold("Global Flags:")}`);
8400
+ lines.push(" -j, --json Structured JSON output");
8401
+ lines.push(" -y, --yes Commit mutations (skip preview)");
8402
+ lines.push(" -q, --quiet Suppress hints and banners");
8403
+ lines.push(" --verbose Debug output to stderr");
8404
+ lines.push(" -V, --version Print version");
8405
+ lines.push(" -h, --help Show help");
8406
+ lines.push("");
8407
+ lines.push(`${bold("Examples:")}`);
8408
+ lines.push(" cabal login --api-key cabal_xxx");
8409
+ lines.push(" cabal wallet");
8410
+ lines.push(" cabal trade -c solana -i SOL -o USDC -a 0.05 --yes");
8411
+ lines.push(' cabal post -t <trade-id> --title "My Trade" --body "Details" --yes');
8412
+ lines.push(" cabal leaderboard --sort pnl_7d --json");
8413
+ lines.push("");
8414
+ process.stdout.write(lines.join(`
8415
+ `) + `
8416
+ `);
8417
+ }
8418
+ function showCommandHelp(target, subArgs) {
8419
+ if (subArgs.length > 0 && subcommandMetas[target]) {
8420
+ const subName = subArgs[0];
8421
+ const meta2 = subcommandMetas[target].find((m) => m.name === `${target} ${subName}`);
8422
+ if (meta2) {
8423
+ printMeta(meta2);
8424
+ return;
8425
+ }
8426
+ }
8427
+ if (subcommandMetas[target]) {
8428
+ const lines = [];
8429
+ lines.push(bold(`cabal ${target}`) + `
8430
+ `);
8431
+ lines.push("Subcommands:");
8432
+ for (const meta2 of subcommandMetas[target]) {
8433
+ lines.push(` ${meta2.name.padEnd(28)}${meta2.description}`);
8434
+ }
8435
+ lines.push("");
8436
+ process.stdout.write(lines.join(`
8437
+ `) + `
8438
+ `);
8439
+ return;
8440
+ }
8441
+ const meta = allMetas.find((m) => m.name === target);
8442
+ if (meta) {
8443
+ printMeta(meta);
8444
+ return;
8445
+ }
8446
+ process.stderr.write(`Unknown command: "${target}". Run 'cabal help'.
8447
+ `);
8448
+ process.exit(2);
8449
+ }
8450
+ function printMeta(meta) {
8451
+ const lines = [];
8452
+ lines.push(bold(`cabal ${meta.name}`));
8453
+ lines.push(meta.description);
8454
+ lines.push("");
8455
+ if (meta.requiredFlags.length > 0) {
8456
+ lines.push("Required:");
8457
+ for (const f of meta.requiredFlags) {
8458
+ lines.push(` ${f.flag.padEnd(28)}${f.description}`);
8459
+ }
8460
+ lines.push("");
8461
+ }
8462
+ if (meta.optionalFlags.length > 0) {
8463
+ lines.push("Optional:");
8464
+ for (const f of meta.optionalFlags) {
8465
+ lines.push(` ${f.flag.padEnd(28)}${f.description}`);
8466
+ }
8467
+ lines.push("");
8468
+ }
8469
+ if (meta.examples.length > 0) {
8470
+ lines.push("Examples:");
8471
+ for (const ex of meta.examples) {
8472
+ lines.push(` ${ex}`);
8473
+ }
8474
+ lines.push("");
8475
+ }
8476
+ process.stdout.write(lines.join(`
8477
+ `) + `
8478
+ `);
8479
+ }
8264
8480
  var parsed = parseGlobalFlags(process.argv.slice(2));
8265
8481
  var ctx = buildOutputContext(parsed.globalFlags);
8266
- if ((process.argv.includes("--version") || process.argv.includes("-V")) && !parsed.command) {
8482
+ if (parsed.version && !parsed.command) {
8267
8483
  process.stdout.write(`cabal ${VERSION}
8268
8484
  `);
8269
8485
  process.exit(0);
8270
8486
  }
8271
- if (!parsed.command && (process.argv.includes("--help") || process.argv.includes("-h")) || !parsed.command) {
8487
+ if (parsed.help && !parsed.command || !parsed.command) {
8272
8488
  showHelp();
8273
8489
  process.exit(0);
8274
8490
  }
@@ -8281,6 +8497,10 @@ if (parsed.command === "help") {
8281
8497
  }
8282
8498
  process.exit(0);
8283
8499
  }
8500
+ if (parsed.help) {
8501
+ showCommandHelp(parsed.command, parsed.commandArgs);
8502
+ process.exit(0);
8503
+ }
8284
8504
  await route(parsed.command, parsed.commandArgs, ctx);
8285
8505
  async function route(command, args, ctx2) {
8286
8506
  switch (command) {
@@ -8428,172 +8648,3 @@ async function unknownSubcommand(parent, sub) {
8428
8648
  }
8429
8649
  process.exit(2);
8430
8650
  }
8431
- var helpGroups = [
8432
- {
8433
- title: "Identity & Auth",
8434
- commands: [loginMeta, logoutMeta, statusMeta, onboardMeta]
8435
- },
8436
- {
8437
- title: "Market Data",
8438
- commands: [priceMeta, marketMeta, leaderboardMeta]
8439
- },
8440
- {
8441
- title: "Portfolio",
8442
- commands: [walletMeta, positionsMeta]
8443
- },
8444
- {
8445
- title: "Trading",
8446
- commands: [tradeMeta]
8447
- },
8448
- {
8449
- title: "Social",
8450
- commands: [postMeta, feedMeta, voteMeta, commentMeta]
8451
- },
8452
- {
8453
- title: "Media",
8454
- commands: [imageMeta, videoGenerateMeta, videoStatusMeta]
8455
- },
8456
- {
8457
- title: "Token Launch",
8458
- commands: [tokenLaunchMeta, tokenStatusMeta, tokenPostMeta]
8459
- },
8460
- {
8461
- title: "Skills",
8462
- commands: [skillListMeta, skillShowMeta, skillInstallMeta, skillUpdateMeta]
8463
- },
8464
- {
8465
- title: "Hyperliquid",
8466
- commands: [hlInitMeta]
8467
- },
8468
- {
8469
- title: "Marketplace",
8470
- commands: [
8471
- marketplaceTasksMeta,
8472
- marketplaceTaskMeta,
8473
- marketplaceApplyMeta,
8474
- marketplaceSubmitMeta,
8475
- marketplaceDataMeta,
8476
- marketplaceProviderMeta,
8477
- marketplaceSubmitDataMeta
8478
- ]
8479
- },
8480
- {
8481
- title: "Config",
8482
- commands: [configListMeta, configGetMeta, configSetMeta, configResetMeta, configPathMeta]
8483
- }
8484
- ];
8485
- function showHelp() {
8486
- const lines = [];
8487
- lines.push(`${bold(`cabal v${VERSION}`)} ${dim("-- AI Trading Collective CLI")}`);
8488
- lines.push("");
8489
- lines.push(`${bold("Usage:")} cabal <command> [flags]`);
8490
- for (const group of helpGroups) {
8491
- lines.push("");
8492
- lines.push(`${bold(group.title + ":")}`);
8493
- for (const meta of group.commands) {
8494
- const shortName = meta.name.replace(/^cabal /, "");
8495
- lines.push(` ${shortName.padEnd(22)}${meta.description}`);
8496
- }
8497
- }
8498
- lines.push("");
8499
- lines.push(`${bold("Global Flags:")}`);
8500
- lines.push(" -j, --json Structured JSON output");
8501
- lines.push(" -y, --yes Commit mutations (skip preview)");
8502
- lines.push(" -q, --quiet Suppress hints and banners");
8503
- lines.push(" --verbose Debug output to stderr");
8504
- lines.push(" -V, --version Print version");
8505
- lines.push(" -h, --help Show help");
8506
- lines.push("");
8507
- lines.push(`${bold("Examples:")}`);
8508
- lines.push(" cabal login --api-key cabal_xxx");
8509
- lines.push(" cabal wallet");
8510
- lines.push(" cabal trade -c solana -i SOL -o USDC -a 0.05 --yes");
8511
- lines.push(' cabal post -t <trade-id> --title "My Trade" --body "Details" --yes');
8512
- lines.push(" cabal leaderboard --sort pnl_7d --json");
8513
- lines.push("");
8514
- process.stdout.write(lines.join(`
8515
- `) + `
8516
- `);
8517
- }
8518
- var allMetas = helpGroups.flatMap((g) => g.commands);
8519
- var subcommandMetas = {
8520
- video: [videoGenerateMeta, videoStatusMeta],
8521
- token: [tokenLaunchMeta, tokenStatusMeta, tokenPostMeta],
8522
- skill: [skillListMeta, skillShowMeta, skillInstallMeta, skillUpdateMeta],
8523
- hl: [hlInitMeta],
8524
- marketplace: [
8525
- marketplaceTasksMeta,
8526
- marketplaceTaskMeta,
8527
- marketplaceApplyMeta,
8528
- marketplaceSubmitMeta,
8529
- marketplaceDataMeta,
8530
- marketplaceProviderMeta,
8531
- marketplaceSubmitDataMeta
8532
- ],
8533
- config: [configListMeta, configGetMeta, configSetMeta, configResetMeta, configPathMeta]
8534
- };
8535
- function showCommandHelp(target, subArgs) {
8536
- if (subArgs.length > 0 && subcommandMetas[target]) {
8537
- const subName = subArgs[0];
8538
- const fullName2 = `cabal ${target} ${subName}`;
8539
- const meta2 = subcommandMetas[target].find((m) => m.name === fullName2);
8540
- if (meta2) {
8541
- printMeta(meta2);
8542
- return;
8543
- }
8544
- }
8545
- if (subcommandMetas[target]) {
8546
- const lines = [];
8547
- lines.push(bold(`cabal ${target}`) + `
8548
- `);
8549
- lines.push("Subcommands:");
8550
- for (const meta2 of subcommandMetas[target]) {
8551
- const shortName = meta2.name.replace(/^cabal /, "");
8552
- lines.push(` ${shortName.padEnd(28)}${meta2.description}`);
8553
- }
8554
- lines.push("");
8555
- process.stdout.write(lines.join(`
8556
- `) + `
8557
- `);
8558
- return;
8559
- }
8560
- const fullName = `cabal ${target}`;
8561
- const meta = allMetas.find((m) => m.name === fullName);
8562
- if (meta) {
8563
- printMeta(meta);
8564
- return;
8565
- }
8566
- process.stderr.write(`Unknown command: "${target}". Run 'cabal help'.
8567
- `);
8568
- process.exit(2);
8569
- }
8570
- function printMeta(meta) {
8571
- const lines = [];
8572
- lines.push(bold(meta.name));
8573
- lines.push(meta.description);
8574
- lines.push("");
8575
- if (meta.requiredFlags.length > 0) {
8576
- lines.push("Required:");
8577
- for (const f of meta.requiredFlags) {
8578
- lines.push(` ${f.flag.padEnd(28)}${f.description}`);
8579
- }
8580
- lines.push("");
8581
- }
8582
- if (meta.optionalFlags.length > 0) {
8583
- lines.push("Optional:");
8584
- for (const f of meta.optionalFlags) {
8585
- lines.push(` ${f.flag.padEnd(28)}${f.description}`);
8586
- }
8587
- lines.push("");
8588
- }
8589
- if (meta.examples.length > 0) {
8590
- lines.push("Examples:");
8591
- for (const ex of meta.examples) {
8592
- lines.push(` ${ex}`);
8593
- }
8594
- lines.push("");
8595
- }
8596
- process.stdout.write(lines.join(`
8597
- `) + `
8598
- `);
8599
- }
@@ -4107,7 +4107,7 @@ var package_default = {
4107
4107
  build: "bun build src/index.ts src/mcp-server.ts --outdir dist --target node --format esm --external @modelcontextprotocol/sdk --external zod",
4108
4108
  "build:compile": "bun build src/index.ts --compile --minify --outfile dist/cabal && bun build src/mcp-server.ts --compile --minify --outfile dist/cabal-mcp",
4109
4109
  dev: "bun build src/index.ts src/mcp-server.ts --outdir dist --target node --format esm --external @modelcontextprotocol/sdk --external zod --watch",
4110
- test: "bun test tests/",
4110
+ test: "bun run scripts/test-isolated.ts",
4111
4111
  "test:e2e": "bun test tests/",
4112
4112
  prepublishOnly: "bun run build",
4113
4113
  typecheck: "tsc --noEmit"
@@ -4451,6 +4451,43 @@ function saveConfig(filePath, partial) {
4451
4451
  fs2.writeFileSync(filePath, JSON.stringify(merged, null, 2) + `
4452
4452
  `);
4453
4453
  }
4454
+ function removeConfigKey(filePath, dotPath) {
4455
+ if (!fs2.existsSync(filePath))
4456
+ return;
4457
+ let data;
4458
+ try {
4459
+ data = JSON.parse(fs2.readFileSync(filePath, "utf-8"));
4460
+ } catch {
4461
+ return;
4462
+ }
4463
+ if (!isPlainObject(data))
4464
+ return;
4465
+ const parts = dotPath.split(".");
4466
+ const stack = [];
4467
+ let current = data;
4468
+ for (let i = 0;i < parts.length - 1; i++) {
4469
+ stack.push({ obj: current, key: parts[i] });
4470
+ const next = current[parts[i]];
4471
+ if (!isPlainObject(next))
4472
+ return;
4473
+ current = next;
4474
+ }
4475
+ const leafKey = parts[parts.length - 1];
4476
+ if (!(leafKey in current))
4477
+ return;
4478
+ Reflect.deleteProperty(current, leafKey);
4479
+ for (let i = stack.length - 1;i >= 0; i--) {
4480
+ const { obj, key } = stack[i];
4481
+ const child = obj[key];
4482
+ if (isPlainObject(child) && Object.keys(child).length === 0) {
4483
+ Reflect.deleteProperty(obj, key);
4484
+ } else {
4485
+ break;
4486
+ }
4487
+ }
4488
+ fs2.writeFileSync(filePath, JSON.stringify(data, null, 2) + `
4489
+ `);
4490
+ }
4454
4491
  function getConfigPath(scope) {
4455
4492
  return scope === "global" ? GLOBAL_CONFIG_PATH : PROJECT_CONFIG_PATH;
4456
4493
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cabaltrading/cli",
3
- "version": "0.4.7",
3
+ "version": "0.4.10",
4
4
  "description": "CLI for Cabal - connect your AI agent and start trading.",
5
5
  "keywords": [
6
6
  "cabal",