@vultisig/cli 0.24.0 → 0.25.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.
Files changed (3) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/index.js +163 -132
  3. package/package.json +7 -7
package/CHANGELOG.md CHANGED
@@ -1,5 +1,41 @@
1
1
  # @vultisig/cli
2
2
 
3
+ ## 0.25.0
4
+
5
+ ### Patch Changes
6
+
7
+ - [#500](https://github.com/vultisig/vultisig-sdk/pull/500) [`46bb0ff`](https://github.com/vultisig/vultisig-sdk/commit/46bb0ff399fef2b082c906a097e10ebb223682a8) Thanks [@neavra](https://github.com/neavra)! - agent: report honest tool success instead of a hardcoded `true`
8
+
9
+ The agent CLI reported every finished server-side tool as `success: true`
10
+ regardless of outcome. `session.ts` hardcoded the result and `client.ts`
11
+ discarded the `tool-output-available` payload, so a failed `execute_send` /
12
+ `execute_swap` (invalid address, insufficient balance, no swap route, signing
13
+ failure) surfaced as a success to programmatic consumers (the `--via-agent`
14
+ pipe, automation, UI status). The client now derives success from the tool's
15
+ output payload (`{"status":"error"}` / `{"error"}` / stringified), passed
16
+ through `onToolProgress`; `ok ?? true` keeps the prior optimistic default when
17
+ no output is present so older backends cannot regress legitimate successes.
18
+
19
+ - Updated dependencies [[`c2fd086`](https://github.com/vultisig/vultisig-sdk/commit/c2fd08670ad67e9ec93443569f9b9b9aa5f9d685), [`7b384c8`](https://github.com/vultisig/vultisig-sdk/commit/7b384c89cb0fd82e76161feee78eccbc2c4401eb), [`585c177`](https://github.com/vultisig/vultisig-sdk/commit/585c177d4de4960a764f2528aa48aebc42450f7d), [`1667b79`](https://github.com/vultisig/vultisig-sdk/commit/1667b79fbc754e36032942fb5e749706dfc09bf3), [`46274d7`](https://github.com/vultisig/vultisig-sdk/commit/46274d70fe19fb2f44bc90d9ec0cd4ac1994ae69), [`0c9f6d5`](https://github.com/vultisig/vultisig-sdk/commit/0c9f6d5139d4a096645a575505c7550c2b26bd2a)]:
20
+ - @vultisig/sdk@0.25.0
21
+ - @vultisig/core-chain@2.1.0
22
+ - @vultisig/client-shared@0.2.9
23
+ - @vultisig/rujira@20.0.0
24
+
25
+ ## 0.24.1
26
+
27
+ ### Patch Changes
28
+
29
+ - [#481](https://github.com/vultisig/vultisig-sdk/pull/481) [`4c98524`](https://github.com/vultisig/vultisig-sdk/commit/4c9852427abccd276759927f990bf22a7ef50513) Thanks [@neavra](https://github.com/neavra)! - agent: forward vault `chain_public_keys` in the chat request context
30
+
31
+ The CLI agent client now sends the vault's per-chain hardened-derived public
32
+ keys (`vault.data.chainPublicKeys`) to agent-backend, nested in the message
33
+ `context` as `chain_public_keys`. This matches agent-backend's
34
+ `MessageContext.ChainPublicKeys` contract and closes the last parity gap with
35
+ vultiagent-app: hardened-derivation chains (Solana, Sui, Polkadot, Terra) now
36
+ get the correct address via the CLI agent path instead of the fallback BIP32
37
+ derivation. Standard MPC vaults omit the field entirely (no empty `{}`).
38
+
3
39
  ## 0.24.0
4
40
 
5
41
  ### Patch Changes
package/dist/index.js CHANGED
@@ -5,16 +5,10 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
9
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
10
- }) : x)(function(x) {
11
- if (typeof require !== "undefined") return require.apply(this, arguments);
12
- throw Error('Dynamic require of "' + x + '" is not supported');
13
- });
14
8
  var __esm = (fn, res) => function __init() {
15
9
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
16
10
  };
17
- var __commonJS = (cb, mod) => function __require2() {
11
+ var __commonJS = (cb, mod) => function __require() {
18
12
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
19
13
  };
20
14
  var __export = (target, all) => {
@@ -4056,60 +4050,78 @@ async function executeSwapQuote(ctx2, options) {
4056
4050
  info('\nTo execute this swap, use the "swap" command');
4057
4051
  return quote;
4058
4052
  }
4059
- async function executeSwap(ctx2, options) {
4060
- const vault = await ctx2.ensureActiveVault();
4061
- const isMax = options.amount === "max";
4062
- if (!isMax && (isNaN(options.amount) || options.amount <= 0)) {
4063
- throw new Error("Invalid amount");
4064
- }
4065
- const amountStr = isMax ? "max" : String(options.amount);
4066
- const quoteSpinner = createSpinner("Getting swap quote...");
4067
- const dryResult = await vault.swap({
4053
+ function validateSwapAmount(amount) {
4054
+ if (amount === "max") return;
4055
+ if (isNaN(amount) || amount <= 0) throw new Error("Invalid amount");
4056
+ }
4057
+ function getSwapAmountString(amount) {
4058
+ return amount === "max" ? "max" : String(amount);
4059
+ }
4060
+ function toSwapRequest(options, amount, dryRun) {
4061
+ return {
4068
4062
  fromChain: options.fromChain,
4069
4063
  fromSymbol: options.fromToken || "",
4070
4064
  toChain: options.toChain,
4071
4065
  toSymbol: options.toToken || "",
4072
- amount: amountStr,
4073
- dryRun: true
4074
- });
4066
+ amount,
4067
+ ...dryRun && { dryRun: true }
4068
+ };
4069
+ }
4070
+ function toDryRunResult(options, quote, fromAmountRaw) {
4071
+ const result = {
4072
+ dryRun: true,
4073
+ fromChain: String(options.fromChain),
4074
+ fromToken: quote.fromCoin.ticker,
4075
+ toChain: String(options.toChain),
4076
+ toToken: quote.toCoin.ticker,
4077
+ inputAmount: fromAmountRaw,
4078
+ ...options.amount === "max" && { isMax: true },
4079
+ estimatedOutput: formatBigintAmount(quote.estimatedOutput, quote.toCoin.decimals),
4080
+ provider: quote.provider
4081
+ };
4082
+ if (quote.estimatedOutputFiat != null) result.estimatedOutputFiat = parseFloat(quote.estimatedOutputFiat.toFixed(2));
4083
+ if (quote.requiresApproval) result.requiresApproval = true;
4084
+ if (quote.warnings?.length) result.warnings = [...quote.warnings];
4085
+ return result;
4086
+ }
4087
+ function displayDryRunResult(result) {
4088
+ info(`
4089
+ Dry-run preview:`);
4090
+ info(` From: ${result.inputAmount} ${result.fromToken} (${result.fromChain})`);
4091
+ info(` To: ${result.estimatedOutput} ${result.toToken} (${result.toChain})`);
4092
+ info(` Provider: ${result.provider}`);
4093
+ if (result.estimatedOutputFiat != null) info(` Est. value (USD): $${result.estimatedOutputFiat}`);
4094
+ if (result.requiresApproval) info(` Requires approval: yes`);
4095
+ if (result.warnings?.length) result.warnings.forEach((w) => warn(` Warning: ${w}`));
4096
+ }
4097
+ async function confirmSwapIfNeeded(options) {
4098
+ if (options.yes) return;
4099
+ if (isNonInteractive()) {
4100
+ throw new Error("Swap requires confirmation. Use --yes to skip, or --dry-run to preview.");
4101
+ }
4102
+ const confirmed = await confirmSwap();
4103
+ if (!confirmed) {
4104
+ warn("Swap cancelled");
4105
+ throw new Error("Swap cancelled by user");
4106
+ }
4107
+ }
4108
+ async function executeSwap(ctx2, options) {
4109
+ const vault = await ctx2.ensureActiveVault();
4110
+ validateSwapAmount(options.amount);
4111
+ const amountStr = getSwapAmountString(options.amount);
4112
+ const quoteSpinner = createSpinner("Getting swap quote...");
4113
+ const dryResult = await vault.swap(toSwapRequest(options, amountStr, true));
4075
4114
  if (!dryResult.dryRun) throw new Error("unreachable");
4076
4115
  quoteSpinner.succeed("Quote received");
4077
4116
  const quote = dryResult.quote;
4078
- const fromAmountRaw = isMax ? formatBigintAmount(quote.maxSwapable, quote.fromCoin.decimals) : String(options.amount);
4079
- const fromAmountDisplay = isMax ? `${fromAmountRaw} (max)` : fromAmountRaw;
4117
+ const fromAmountRaw = options.amount === "max" ? formatBigintAmount(quote.maxSwapable, quote.fromCoin.decimals) : String(options.amount);
4118
+ const fromAmountDisplay = options.amount === "max" ? `${fromAmountRaw} (max)` : fromAmountRaw;
4080
4119
  if (options.dryRun) {
4081
- const estimatedOutput = formatBigintAmount(quote.estimatedOutput, quote.toCoin.decimals);
4082
- const result = {
4083
- dryRun: true,
4084
- fromChain: String(options.fromChain),
4085
- fromToken: quote.fromCoin.ticker,
4086
- toChain: String(options.toChain),
4087
- toToken: quote.toCoin.ticker,
4088
- inputAmount: fromAmountRaw,
4089
- ...isMax && { isMax: true },
4090
- estimatedOutput,
4091
- provider: quote.provider
4092
- };
4093
- if (quote.estimatedOutputFiat != null) {
4094
- result.estimatedOutputFiat = parseFloat(quote.estimatedOutputFiat.toFixed(2));
4095
- }
4096
- if (quote.requiresApproval) {
4097
- result.requiresApproval = true;
4098
- }
4099
- if (quote.warnings && quote.warnings.length > 0) {
4100
- result.warnings = [...quote.warnings];
4101
- }
4120
+ const result = toDryRunResult(options, quote, fromAmountRaw);
4102
4121
  if (isJsonOutput()) {
4103
4122
  outputJson(result);
4104
4123
  } else {
4105
- info(`
4106
- Dry-run preview:`);
4107
- info(` From: ${result.inputAmount} ${result.fromToken} (${result.fromChain})`);
4108
- info(` To: ${result.estimatedOutput} ${result.toToken} (${result.toChain})`);
4109
- info(` Provider: ${result.provider}`);
4110
- if (result.estimatedOutputFiat != null) info(` Est. value (USD): $${result.estimatedOutputFiat}`);
4111
- if (result.requiresApproval) info(` Requires approval: yes`);
4112
- if (result.warnings?.length) result.warnings.forEach((w) => warn(` Warning: ${w}`));
4124
+ displayDryRunResult(result);
4113
4125
  }
4114
4126
  return result;
4115
4127
  }
@@ -4124,29 +4136,14 @@ Dry-run preview:`);
4124
4136
  discountTier
4125
4137
  });
4126
4138
  }
4127
- if (!options.yes) {
4128
- if (isNonInteractive()) {
4129
- throw new Error("Swap requires confirmation. Use --yes to skip, or --dry-run to preview.");
4130
- }
4131
- const confirmed = await confirmSwap();
4132
- if (!confirmed) {
4133
- warn("Swap cancelled");
4134
- throw new Error("Swap cancelled by user");
4135
- }
4136
- }
4139
+ await confirmSwapIfNeeded(options);
4137
4140
  await ensureVaultUnlocked(vault, options.password);
4138
4141
  const signSpinner = createSpinner("Signing swap transaction...");
4139
4142
  vault.on("signingProgress", ({ step }) => {
4140
4143
  signSpinner.text = `${step.message} (${step.progress}%)`;
4141
4144
  });
4142
4145
  try {
4143
- const result = await vault.swap({
4144
- fromChain: options.fromChain,
4145
- fromSymbol: options.fromToken || "",
4146
- toChain: options.toChain,
4147
- toSymbol: options.toToken || "",
4148
- amount: amountStr
4149
- });
4146
+ const result = await vault.swap(toSwapRequest(options, amountStr));
4150
4147
  if (result.dryRun) throw new Error("unreachable");
4151
4148
  const broadcast = result;
4152
4149
  signSpinner.succeed(`Swap broadcast: ${broadcast.txHash}`);
@@ -4944,6 +4941,28 @@ function v1StatusFromType(type) {
4944
4941
  return void 0;
4945
4942
  }
4946
4943
  }
4944
+ function isErrorPayloadObject(o) {
4945
+ return o.status === "error" || "error" in o;
4946
+ }
4947
+ function deriveToolDoneOk(status, output) {
4948
+ if (status !== "done" || output == null) return void 0;
4949
+ if (typeof output === "object") {
4950
+ return !isErrorPayloadObject(output);
4951
+ }
4952
+ if (typeof output === "string") {
4953
+ const s = output.trim();
4954
+ if (/^error\b/i.test(s)) return false;
4955
+ try {
4956
+ const parsed = JSON.parse(s);
4957
+ if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
4958
+ return !isErrorPayloadObject(parsed);
4959
+ }
4960
+ } catch {
4961
+ }
4962
+ return !(/"status"\s*:\s*"error"/i.test(s) || /"error"\s*:/i.test(s));
4963
+ }
4964
+ return true;
4965
+ }
4947
4966
  function sseErrorToMessage(value) {
4948
4967
  if (value == null) return "";
4949
4968
  if (typeof value === "string") return value;
@@ -4955,6 +4974,16 @@ function sseErrorToMessage(value) {
4955
4974
  return String(value);
4956
4975
  }
4957
4976
  }
4977
+ function getV1Type(parsed) {
4978
+ return typeof parsed?.type === "string" && parsed.type.length > 0 ? parsed.type : null;
4979
+ }
4980
+ function getV1Data(parsed, v1Type) {
4981
+ return v1Type?.startsWith("data-") ? parsed.data : null;
4982
+ }
4983
+ function getToolInput(parsed) {
4984
+ const rawInput = parsed.input;
4985
+ return rawInput && typeof rawInput === "object" && !Array.isArray(rawInput) ? rawInput : {};
4986
+ }
4958
4987
  var AgentClient = class {
4959
4988
  baseUrl;
4960
4989
  authToken = null;
@@ -5104,40 +5133,16 @@ var AgentClient = class {
5104
5133
  handleSSEEvent(event, data, result, callbacks, toolNameByCallId) {
5105
5134
  try {
5106
5135
  const parsed = JSON.parse(data);
5107
- const v1Type = typeof parsed?.type === "string" && parsed.type.length > 0 ? parsed.type : null;
5136
+ const v1Type = getV1Type(parsed);
5108
5137
  const routingEvent = v1Type ? this.mapV1EventType(v1Type) : event;
5109
- const v1Data = typeof parsed?.type === "string" && parsed.type.startsWith("data-") ? parsed.data : null;
5138
+ const v1Data = getV1Data(parsed, v1Type);
5110
5139
  switch (routingEvent) {
5111
5140
  case "text_delta":
5112
- if (typeof parsed.delta === "string") {
5113
- result.fullText += parsed.delta;
5114
- callbacks.onTextDelta?.(parsed.delta);
5115
- }
5141
+ this.handleTextDelta(parsed, result, callbacks);
5116
5142
  break;
5117
- case "tool_progress": {
5118
- if (this.verbose) process.stderr.write(`[SSE:tool_progress] raw: ${data.slice(0, 1e3)}
5119
- `);
5120
- const v1Status = v1StatusFromType(v1Type);
5121
- const status = parsed.status ?? v1Status;
5122
- const callId = typeof parsed.toolCallId === "string" ? parsed.toolCallId : null;
5123
- const rawInlineName = parsed.tool ?? parsed.toolName;
5124
- const inlineName = typeof rawInlineName === "string" && rawInlineName.length > 0 ? rawInlineName : void 0;
5125
- if (callId && inlineName) {
5126
- toolNameByCallId.set(callId, inlineName);
5127
- }
5128
- const toolName = inlineName ?? (callId ? toolNameByCallId.get(callId) : void 0);
5129
- const label = typeof parsed.label === "string" ? parsed.label : void 0;
5130
- if (v1Type === "tool-input-available" && parsed.clientExecuted === true && callId && toolName && callbacks.onClientSideToolCall) {
5131
- const rawInput = parsed.input;
5132
- const input = rawInput && typeof rawInput === "object" && !Array.isArray(rawInput) ? rawInput : {};
5133
- callbacks.onClientSideToolCall(callId, toolName, input);
5134
- }
5135
- if (status && toolName) {
5136
- callbacks.onToolProgress?.(toolName, status, label);
5137
- }
5138
- if (status === "done" && callId) toolNameByCallId.delete(callId);
5143
+ case "tool_progress":
5144
+ this.handleToolProgress(parsed, data, callbacks, toolNameByCallId, v1Type);
5139
5145
  break;
5140
- }
5141
5146
  case "title": {
5142
5147
  const title = v1Data?.title ?? parsed.title;
5143
5148
  if (typeof title === "string") callbacks.onTitle?.(title);
@@ -5165,10 +5170,7 @@ var AgentClient = class {
5165
5170
  break;
5166
5171
  }
5167
5172
  case "error": {
5168
- const errorText = typeof parsed.errorText === "string" ? parsed.errorText : parsed.error;
5169
- const msg = sseErrorToMessage(errorText);
5170
- const codeFromBackend = typeof parsed.code === "string" && isAgentErrorCode(parsed.code) ? parsed.code : inferAgentErrorCodeFromMessage(msg);
5171
- callbacks.onError?.(msg, codeFromBackend);
5173
+ this.handleErrorEvent(parsed, callbacks);
5172
5174
  break;
5173
5175
  }
5174
5176
  case "done":
@@ -5183,6 +5185,38 @@ var AgentClient = class {
5183
5185
  }
5184
5186
  }
5185
5187
  }
5188
+ handleTextDelta(parsed, result, callbacks) {
5189
+ if (typeof parsed.delta !== "string") return;
5190
+ result.fullText += parsed.delta;
5191
+ callbacks.onTextDelta?.(parsed.delta);
5192
+ }
5193
+ handleToolProgress(parsed, data, callbacks, toolNameByCallId, v1Type) {
5194
+ if (this.verbose) process.stderr.write(`[SSE:tool_progress] raw: ${data.slice(0, 1e3)}
5195
+ `);
5196
+ const status = parsed.status ?? v1StatusFromType(v1Type);
5197
+ const callId = typeof parsed.toolCallId === "string" ? parsed.toolCallId : null;
5198
+ const rawInlineName = parsed.tool ?? parsed.toolName;
5199
+ const inlineName = typeof rawInlineName === "string" && rawInlineName.length > 0 ? rawInlineName : void 0;
5200
+ if (callId && inlineName) toolNameByCallId.set(callId, inlineName);
5201
+ const toolName = inlineName ?? (callId ? toolNameByCallId.get(callId) : void 0);
5202
+ const label = typeof parsed.label === "string" ? parsed.label : void 0;
5203
+ this.maybeEmitClientSideToolCall(parsed, callbacks, v1Type, callId, toolName);
5204
+ const ok = deriveToolDoneOk(status, parsed.output);
5205
+ if (status && toolName) callbacks.onToolProgress?.(toolName, status, label, ok);
5206
+ if (status === "done" && callId) toolNameByCallId.delete(callId);
5207
+ }
5208
+ maybeEmitClientSideToolCall(parsed, callbacks, v1Type, callId, toolName) {
5209
+ if (v1Type !== "tool-input-available" || parsed.clientExecuted !== true || !callId || !toolName || !callbacks.onClientSideToolCall) {
5210
+ return;
5211
+ }
5212
+ callbacks.onClientSideToolCall(callId, toolName, getToolInput(parsed));
5213
+ }
5214
+ handleErrorEvent(parsed, callbacks) {
5215
+ const errorText = typeof parsed.errorText === "string" ? parsed.errorText : parsed.error;
5216
+ const msg = sseErrorToMessage(errorText);
5217
+ const codeFromBackend = typeof parsed.code === "string" && isAgentErrorCode(parsed.code) ? parsed.code : inferAgentErrorCodeFromMessage(msg);
5218
+ callbacks.onError?.(msg, codeFromBackend);
5219
+ }
5186
5220
  // Maps a V1 `type` field to the legacy event bucket used by handleSSEEvent's
5187
5221
  // switch. Frame-level types (start, text-start, text-end, finish-step) and
5188
5222
  // non-critical telemetry (data-tokens, data-usage, data-confirmation) route
@@ -5250,12 +5284,27 @@ var AgentClient = class {
5250
5284
 
5251
5285
  // src/agent/context.ts
5252
5286
  import { Chain as Chain8 } from "@vultisig/sdk";
5287
+ function applyChainPublicKeys(vault, context) {
5288
+ const raw = vault.data.chainPublicKeys;
5289
+ if (!raw) return;
5290
+ const serialized = {};
5291
+ for (const chain of Object.keys(raw)) {
5292
+ const pubkey = raw[chain];
5293
+ if (typeof pubkey === "string" && pubkey.length > 0) {
5294
+ serialized[chain] = pubkey;
5295
+ }
5296
+ }
5297
+ if (Object.keys(serialized).length > 0) {
5298
+ context.chain_public_keys = serialized;
5299
+ }
5300
+ }
5253
5301
  async function buildMessageContext(vault) {
5254
5302
  const context = {
5255
5303
  vault_address: vault.publicKeys.ecdsa,
5256
5304
  vault_name: vault.name,
5257
5305
  mldsa_public_key: vault.publicKeyMldsa
5258
5306
  };
5307
+ applyChainPublicKeys(vault, context);
5259
5308
  try {
5260
5309
  const chains = vault.chains;
5261
5310
  const addressEntries = await Promise.allSettled(
@@ -5319,6 +5368,7 @@ async function buildMinimalContext(vault) {
5319
5368
  vault_address: vault.publicKeys.ecdsa,
5320
5369
  vault_name: vault.name
5321
5370
  };
5371
+ applyChainPublicKeys(vault, context);
5322
5372
  try {
5323
5373
  const chains = vault.chains;
5324
5374
  const addressEntries = await Promise.allSettled(
@@ -5463,17 +5513,8 @@ var Chain9 = {
5463
5513
  ...CosmosChain,
5464
5514
  ...OtherChain
5465
5515
  };
5466
- var UtxoBasedChain = [
5467
- ...Object.values(UtxoChain),
5468
- OtherChain.Cardano
5469
- ];
5470
- var defaultChains = [
5471
- Chain9.Bitcoin,
5472
- Chain9.Ethereum,
5473
- Chain9.THORChain,
5474
- Chain9.Solana,
5475
- Chain9.BSC
5476
- ];
5516
+ var UtxoBasedChain = [...Object.values(UtxoChain), OtherChain.Cardano];
5517
+ var defaultChains = [Chain9.Bitcoin, Chain9.Ethereum, Chain9.THORChain, Chain9.Solana, Chain9.BSC];
5477
5518
 
5478
5519
  // ../../packages/core/chain/dist/ChainKind.js
5479
5520
  var chainKindRecord = {
@@ -5522,10 +5563,7 @@ function getChainKind(chain) {
5522
5563
 
5523
5564
  // ../../packages/lib/utils/dist/record/recordMap.js
5524
5565
  function recordMap(record, fn) {
5525
- return Object.fromEntries(Object.entries(record).map(([key, value]) => [
5526
- key,
5527
- fn(value, key)
5528
- ]));
5566
+ return Object.fromEntries(Object.entries(record).map(([key, value]) => [key, fn(value, key)]));
5529
5567
  }
5530
5568
 
5531
5569
  // ../../packages/lib/utils/dist/record/makeRecord/index.js
@@ -5538,14 +5576,7 @@ var makeRecord = (keys, getValue) => {
5538
5576
  };
5539
5577
 
5540
5578
  // ../../packages/core/chain/dist/chains/cosmos/thor/kujira-merge/index.js
5541
- var kujiraCoinsMigratedToThorChain = [
5542
- "kuji",
5543
- "rkuji",
5544
- "fuzn",
5545
- "nstk",
5546
- "wink",
5547
- "lvn"
5548
- ];
5579
+ var kujiraCoinsMigratedToThorChain = ["kuji", "rkuji", "fuzn", "nstk", "wink", "lvn"];
5549
5580
  var kujiraCoinsMigratedToThorChainMetadata = {
5550
5581
  kuji: {
5551
5582
  ticker: "KUJI",
@@ -7935,11 +7966,12 @@ var AgentSession = class {
7935
7966
  let dispatchChain = Promise.resolve();
7936
7967
  const callbacks = {
7937
7968
  onTextDelta: (delta) => ui.onTextDelta(delta),
7938
- onToolProgress: (tool, status, label) => {
7969
+ onToolProgress: (tool, status, label, ok) => {
7939
7970
  if (status === "running") {
7940
7971
  ui.onToolCall(`mcp-${tool}`, tool);
7941
7972
  } else {
7942
- ui.onToolResult(`mcp-${tool}`, tool, true, { label });
7973
+ const success2 = ok ?? true;
7974
+ ui.onToolResult(`mcp-${tool}`, tool, success2, { label }, success2 ? void 0 : `${tool} reported an error`);
7943
7975
  }
7944
7976
  },
7945
7977
  onClientSideToolCall: (toolCallId, toolName, input) => {
@@ -8723,14 +8755,14 @@ function formatDate(iso) {
8723
8755
 
8724
8756
  // src/lib/version.ts
8725
8757
  import chalk10 from "chalk";
8726
- import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, existsSync as existsSync2 } from "fs";
8758
+ import { existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
8727
8759
  import { homedir as homedir3 } from "os";
8728
8760
  import { join as join3 } from "path";
8729
8761
  var cachedVersion = null;
8730
8762
  function getVersion() {
8731
8763
  if (cachedVersion) return cachedVersion;
8732
8764
  if (true) {
8733
- cachedVersion = "0.24.0";
8765
+ cachedVersion = "0.25.0";
8734
8766
  return cachedVersion;
8735
8767
  }
8736
8768
  try {
@@ -10405,13 +10437,10 @@ Error: ${error2.message}`));
10405
10437
  }
10406
10438
  };
10407
10439
 
10408
- // src/lib/errors.ts
10409
- import chalk14 from "chalk";
10410
-
10411
10440
  // src/lib/completion.ts
10441
+ import { existsSync as existsSync3, readdirSync, readFileSync as readFileSync4 } from "fs";
10412
10442
  import { homedir as homedir4 } from "os";
10413
10443
  import { join as join4 } from "path";
10414
- import { readFileSync as readFileSync4, existsSync as existsSync3 } from "fs";
10415
10444
  var tabtab = null;
10416
10445
  async function getTabtab() {
10417
10446
  if (!tabtab) {
@@ -10478,7 +10507,6 @@ function getVaultNames() {
10478
10507
  try {
10479
10508
  const vaultDir = join4(homedir4(), ".vultisig", "vaults");
10480
10509
  if (!existsSync3(vaultDir)) return [];
10481
- const { readdirSync } = __require("fs");
10482
10510
  const files = readdirSync(vaultDir);
10483
10511
  const names = [];
10484
10512
  for (const file of files) {
@@ -10722,6 +10750,9 @@ complete -c vsig -n "__fish_seen_subcommand_from import export" -a "(__fish_comp
10722
10750
  `.trim();
10723
10751
  }
10724
10752
 
10753
+ // src/lib/errors.ts
10754
+ import chalk14 from "chalk";
10755
+
10725
10756
  // src/lib/user-agent.ts
10726
10757
  function setupUserAgent() {
10727
10758
  const userAgent = `vultisig-cli/${getVersion()}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vultisig/cli",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "description": "The self-custody MPC wallet CLI for AI coding agents (Claude Code, Cursor, OpenCode). Natural-language agent mode, 36+ chains, DKLS23 threshold signatures. Seedless.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -73,15 +73,15 @@
73
73
  "@cosmjs/stargate": "^0.38.1",
74
74
  "@napi-rs/keyring": "^1.3.0",
75
75
  "@noble/hashes": "^2.0.1",
76
- "@vultisig/client-shared": "^0.2.8",
77
- "@vultisig/core-chain": "^2.0.0",
78
- "@vultisig/rujira": "^19.0.0",
79
- "@vultisig/sdk": "^0.24.0",
76
+ "@vultisig/client-shared": "^0.2.9",
77
+ "@vultisig/core-chain": "^2.1.0",
78
+ "@vultisig/rujira": "^20.0.0",
79
+ "@vultisig/sdk": "^0.25.0",
80
80
  "chalk": "^5.6.2",
81
81
  "cli-table3": "^0.6.5",
82
82
  "commander": "^14.0.3",
83
83
  "dotenv": "^17.3.1",
84
- "ora": "^9.3.0",
84
+ "ora": "^9.4.0",
85
85
  "qrcode-terminal": "^0.12.0",
86
86
  "tabtab": "^3.0.2",
87
87
  "viem": "^2.48.4",
@@ -95,7 +95,7 @@
95
95
  "esbuild": "^0.27.4",
96
96
  "tsx": "^4.21.0",
97
97
  "typescript": "^6.0.3",
98
- "vitest": "^4.1.5"
98
+ "vitest": "^4.1.6"
99
99
  },
100
100
  "engines": {
101
101
  "node": ">=20.0.0"