@vultisig/cli 2.7.0 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/dist/index.js +109 -61
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @vultisig/cli
|
|
2
2
|
|
|
3
|
+
## 2.8.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#868](https://github.com/vultisig/vultisig-sdk/pull/868) [`6f84f19`](https://github.com/vultisig/vultisig-sdk/commit/6f84f19444752976a6677d3ee4054701b0904eae) Thanks [@neavra](https://github.com/neavra)! - `agent ask --json` now emits one stable v1 envelope on stdout for both success and error. Previously the success envelope was written through a redirected `console.log` and landed on stderr (stdout empty), and the error path wrote a different flat `{error,code}` shape. The envelope now carries `conversation_id` (success + error) and per-tool-call `id`s, and a mid-stream backend/SSE `error` frame makes the command exit non-zero instead of reporting false success.
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [[`c9a235b`](https://github.com/vultisig/vultisig-sdk/commit/c9a235b959c7c82cd189482fab86ce3d27ddb4ff), [`9585b6f`](https://github.com/vultisig/vultisig-sdk/commit/9585b6f246de3ce537eae201f0d660fc89ff1012), [`f82caf5`](https://github.com/vultisig/vultisig-sdk/commit/f82caf58532f58af9d62b0143c7466cabcd88b06), [`361ba58`](https://github.com/vultisig/vultisig-sdk/commit/361ba58f79f241c4c00e33785a66ec6987628d26), [`7625e0b`](https://github.com/vultisig/vultisig-sdk/commit/7625e0bf325c8957bc3e28270454fd54c5589e2f), [`2024a92`](https://github.com/vultisig/vultisig-sdk/commit/2024a92b44760e1ff2043b0e45b083edc131b16c)]:
|
|
10
|
+
- @vultisig/sdk@2.8.0
|
|
11
|
+
- @vultisig/rujira@41.0.0
|
|
12
|
+
|
|
3
13
|
## 2.7.0
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -5053,11 +5053,11 @@ function bigIntReplacer(_key, value) {
|
|
|
5053
5053
|
}
|
|
5054
5054
|
function outputJson(data) {
|
|
5055
5055
|
const transformed = applyOutputTransforms(data);
|
|
5056
|
-
|
|
5056
|
+
process.stdout.write(JSON.stringify({ success: true, v: 1, data: transformed }, bigIntReplacer, 2) + "\n");
|
|
5057
5057
|
}
|
|
5058
5058
|
function outputErrorJson(errJson) {
|
|
5059
5059
|
const transformed = applyOutputTransforms(errJson);
|
|
5060
|
-
|
|
5060
|
+
process.stdout.write(JSON.stringify(transformed, bigIntReplacer, 2) + "\n");
|
|
5061
5061
|
}
|
|
5062
5062
|
function info(message) {
|
|
5063
5063
|
if (!silentMode) {
|
|
@@ -8184,6 +8184,7 @@ var AskInterface = class {
|
|
|
8184
8184
|
toolCalls = [];
|
|
8185
8185
|
transactions = [];
|
|
8186
8186
|
cards = [];
|
|
8187
|
+
error;
|
|
8187
8188
|
constructor(session, verbose = false, autoApprove = false) {
|
|
8188
8189
|
this.session = session;
|
|
8189
8190
|
this.verbose = verbose;
|
|
@@ -8204,8 +8205,8 @@ var AskInterface = class {
|
|
|
8204
8205
|
`);
|
|
8205
8206
|
}
|
|
8206
8207
|
},
|
|
8207
|
-
onToolResult: (
|
|
8208
|
-
this.toolCalls.push({ action, success: success2, data, error: error2, code });
|
|
8208
|
+
onToolResult: (id, action, success2, data, error2, code) => {
|
|
8209
|
+
this.toolCalls.push({ id, action, success: success2, data, error: error2, code });
|
|
8209
8210
|
if (this.verbose) {
|
|
8210
8211
|
const status = success2 ? "ok" : `error: ${error2}${code ? ` [${code}]` : ""}`;
|
|
8211
8212
|
process.stderr.write(`[tool] ${action}: ${status}
|
|
@@ -8222,14 +8223,17 @@ var AskInterface = class {
|
|
|
8222
8223
|
},
|
|
8223
8224
|
onSuggestions: (_suggestions) => {
|
|
8224
8225
|
},
|
|
8225
|
-
onTxStatus: (txHash, chain,
|
|
8226
|
-
this.transactions.push({ hash: txHash, chain, explorerUrl });
|
|
8226
|
+
onTxStatus: (txHash, chain, status, explorerUrl) => {
|
|
8227
|
+
this.transactions.push({ hash: txHash, chain, ...status ? { status } : {}, explorerUrl });
|
|
8227
8228
|
if (this.verbose) {
|
|
8228
8229
|
process.stderr.write(`[tx] ${chain}: ${txHash}
|
|
8229
8230
|
`);
|
|
8230
8231
|
}
|
|
8231
8232
|
},
|
|
8232
8233
|
onError: (message, code) => {
|
|
8234
|
+
if (!this.error) {
|
|
8235
|
+
this.error = { message, code };
|
|
8236
|
+
}
|
|
8233
8237
|
process.stderr.write(`[error] ${message} [${code}]
|
|
8234
8238
|
`);
|
|
8235
8239
|
},
|
|
@@ -8259,14 +8263,27 @@ var AskInterface = class {
|
|
|
8259
8263
|
this.toolCalls = [];
|
|
8260
8264
|
this.transactions = [];
|
|
8261
8265
|
this.cards = [];
|
|
8266
|
+
this.error = void 0;
|
|
8262
8267
|
const callbacks = this.getCallbacks();
|
|
8263
8268
|
await this.session.sendMessage(message, callbacks);
|
|
8269
|
+
return this.partialResult();
|
|
8270
|
+
}
|
|
8271
|
+
/**
|
|
8272
|
+
* Snapshot of everything collected so far this turn. Identical to a normal
|
|
8273
|
+
* `ask()` return, but callable from a catch block when `ask()` THREW mid-turn
|
|
8274
|
+
* — e.g. the follow-up request that reports recent_actions back to the backend
|
|
8275
|
+
* fails (timeout/5xx/auth) AFTER a tx has already broadcast and `onTxStatus`
|
|
8276
|
+
* fired. Lets the caller still surface the already-broadcast tx hash in the
|
|
8277
|
+
* error envelope instead of stranding funds the turn just moved.
|
|
8278
|
+
*/
|
|
8279
|
+
partialResult() {
|
|
8264
8280
|
return {
|
|
8265
8281
|
sessionId: this.session.getConversationId() || "",
|
|
8266
8282
|
response: this.responseParts[this.responseParts.length - 1] || "",
|
|
8267
8283
|
toolCalls: this.toolCalls,
|
|
8268
8284
|
transactions: this.transactions,
|
|
8269
|
-
cards: this.cards
|
|
8285
|
+
cards: this.cards,
|
|
8286
|
+
error: this.error
|
|
8270
8287
|
};
|
|
8271
8288
|
}
|
|
8272
8289
|
};
|
|
@@ -13068,12 +13085,85 @@ async function executeAgent(ctx2, options) {
|
|
|
13068
13085
|
}
|
|
13069
13086
|
}
|
|
13070
13087
|
}
|
|
13088
|
+
function outputAskError(wantsJson, message, code, conversationId, result) {
|
|
13089
|
+
if (wantsJson) {
|
|
13090
|
+
const data = {};
|
|
13091
|
+
if (result?.transactions.length) data.transactions = result.transactions;
|
|
13092
|
+
if (result?.toolCalls.length) data.tool_calls = result.toolCalls;
|
|
13093
|
+
if (result?.response) data.response = result.response;
|
|
13094
|
+
outputErrorJson({
|
|
13095
|
+
success: false,
|
|
13096
|
+
v: 1,
|
|
13097
|
+
error: { message, code, conversation_id: conversationId },
|
|
13098
|
+
...Object.keys(data).length > 0 ? { data } : {}
|
|
13099
|
+
});
|
|
13100
|
+
} else {
|
|
13101
|
+
process.stderr.write(`Error: ${message} [${code}]
|
|
13102
|
+
`);
|
|
13103
|
+
}
|
|
13104
|
+
}
|
|
13105
|
+
function outputAskHuman(result, confirmationRequired, proposed) {
|
|
13106
|
+
process.stdout.write(`session:${result.sessionId}
|
|
13107
|
+
`);
|
|
13108
|
+
if (confirmationRequired) {
|
|
13109
|
+
process.stdout.write(`confirmation-required:pass --yes to authorize signing
|
|
13110
|
+
`);
|
|
13111
|
+
if (proposed) {
|
|
13112
|
+
process.stdout.write(`proposed:${proposed}
|
|
13113
|
+
`);
|
|
13114
|
+
}
|
|
13115
|
+
}
|
|
13116
|
+
for (const card of result.cards) {
|
|
13117
|
+
process.stdout.write(`
|
|
13118
|
+
${renderBalanceSummaryCard(card)}
|
|
13119
|
+
`);
|
|
13120
|
+
}
|
|
13121
|
+
if (result.response) {
|
|
13122
|
+
process.stdout.write(`
|
|
13123
|
+
${result.response}
|
|
13124
|
+
`);
|
|
13125
|
+
}
|
|
13126
|
+
for (const tx of result.transactions) {
|
|
13127
|
+
process.stdout.write(`
|
|
13128
|
+
tx:${tx.chain}:${tx.hash}
|
|
13129
|
+
`);
|
|
13130
|
+
if (tx.explorerUrl) {
|
|
13131
|
+
process.stdout.write(`explorer:${tx.explorerUrl}
|
|
13132
|
+
`);
|
|
13133
|
+
}
|
|
13134
|
+
}
|
|
13135
|
+
}
|
|
13136
|
+
function outputAskSuccess(wantsJson, result, conversationId) {
|
|
13137
|
+
const confirmationRequired = result.toolCalls.some((tc) => tc.code === "CONFIRMATION_REQUIRED" /* CONFIRMATION_REQUIRED */);
|
|
13138
|
+
const proposedCall = result.toolCalls.find(
|
|
13139
|
+
(tc) => tc.code === "CONFIRMATION_REQUIRED" /* CONFIRMATION_REQUIRED */ && typeof tc.data?.proposed === "string"
|
|
13140
|
+
);
|
|
13141
|
+
const proposed = proposedCall?.data?.proposed;
|
|
13142
|
+
if (wantsJson) {
|
|
13143
|
+
outputJson({
|
|
13144
|
+
conversation_id: conversationId,
|
|
13145
|
+
session_id: result.sessionId,
|
|
13146
|
+
response: result.response,
|
|
13147
|
+
tool_calls: result.toolCalls,
|
|
13148
|
+
transactions: result.transactions,
|
|
13149
|
+
...result.cards.length > 0 ? { cards: result.cards } : {},
|
|
13150
|
+
...confirmationRequired ? { confirmation_required: true } : {},
|
|
13151
|
+
...proposed ? { proposed } : {}
|
|
13152
|
+
});
|
|
13153
|
+
return;
|
|
13154
|
+
}
|
|
13155
|
+
outputAskHuman(result, confirmationRequired, proposed);
|
|
13156
|
+
}
|
|
13071
13157
|
async function executeAgentAsk(ctx2, message, options) {
|
|
13072
13158
|
setSilentMode(true);
|
|
13073
13159
|
const originalConsoleLog = console.log;
|
|
13074
13160
|
console.log = (...args) => {
|
|
13075
13161
|
process.stderr.write(args.map(String).join(" ") + "\n");
|
|
13076
13162
|
};
|
|
13163
|
+
const wantsJson = !!options.json || isJsonOutput();
|
|
13164
|
+
let conversationId = "";
|
|
13165
|
+
let exitCode = 0;
|
|
13166
|
+
let ask;
|
|
13077
13167
|
try {
|
|
13078
13168
|
const vault = await ctx2.ensureActiveVault();
|
|
13079
13169
|
const config = {
|
|
@@ -13087,70 +13177,28 @@ async function executeAgentAsk(ctx2, message, options) {
|
|
|
13087
13177
|
profile: options.profile ?? process.env.VULTISIG_AGENT_PROFILE ?? ""
|
|
13088
13178
|
};
|
|
13089
13179
|
const session = new AgentSession(vault, config);
|
|
13090
|
-
|
|
13180
|
+
ask = new AskInterface(session, !!config.verbose, !!options.autoApprove);
|
|
13091
13181
|
const callbacks = ask.getCallbacks();
|
|
13092
13182
|
await session.initialize(callbacks);
|
|
13093
13183
|
const result = await ask.ask(message);
|
|
13094
|
-
|
|
13095
|
-
|
|
13096
|
-
|
|
13097
|
-
|
|
13098
|
-
const proposed = proposedCall?.data?.proposed;
|
|
13099
|
-
if (options.json || isJsonOutput()) {
|
|
13100
|
-
outputJson({
|
|
13101
|
-
session_id: result.sessionId,
|
|
13102
|
-
response: result.response,
|
|
13103
|
-
tool_calls: result.toolCalls,
|
|
13104
|
-
transactions: result.transactions,
|
|
13105
|
-
...result.cards.length > 0 ? { cards: result.cards } : {},
|
|
13106
|
-
...confirmationRequired ? { confirmation_required: true } : {},
|
|
13107
|
-
...proposed ? { proposed } : {}
|
|
13108
|
-
});
|
|
13184
|
+
conversationId = result.sessionId;
|
|
13185
|
+
if (result.error) {
|
|
13186
|
+
exitCode = 1;
|
|
13187
|
+
outputAskError(wantsJson, result.error.message, result.error.code, conversationId, result);
|
|
13109
13188
|
} else {
|
|
13110
|
-
|
|
13111
|
-
`);
|
|
13112
|
-
if (confirmationRequired) {
|
|
13113
|
-
process.stdout.write(`confirmation-required:pass --yes to authorize signing
|
|
13114
|
-
`);
|
|
13115
|
-
if (proposed) {
|
|
13116
|
-
process.stdout.write(`proposed:${proposed}
|
|
13117
|
-
`);
|
|
13118
|
-
}
|
|
13119
|
-
}
|
|
13120
|
-
for (const card of result.cards) {
|
|
13121
|
-
process.stdout.write(`
|
|
13122
|
-
${renderBalanceSummaryCard(card)}
|
|
13123
|
-
`);
|
|
13124
|
-
}
|
|
13125
|
-
if (result.response) {
|
|
13126
|
-
process.stdout.write(`
|
|
13127
|
-
${result.response}
|
|
13128
|
-
`);
|
|
13129
|
-
}
|
|
13130
|
-
for (const tx of result.transactions) {
|
|
13131
|
-
process.stdout.write(`
|
|
13132
|
-
tx:${tx.chain}:${tx.hash}
|
|
13133
|
-
`);
|
|
13134
|
-
if (tx.explorerUrl) {
|
|
13135
|
-
process.stdout.write(`explorer:${tx.explorerUrl}
|
|
13136
|
-
`);
|
|
13137
|
-
}
|
|
13138
|
-
}
|
|
13189
|
+
outputAskSuccess(wantsJson, result, conversationId);
|
|
13139
13190
|
}
|
|
13140
13191
|
} catch (err) {
|
|
13141
13192
|
const { code, message: message2 } = normalizeAgentError(err);
|
|
13142
|
-
|
|
13143
|
-
|
|
13144
|
-
|
|
13145
|
-
|
|
13146
|
-
`);
|
|
13147
|
-
}
|
|
13148
|
-
process.exit(1);
|
|
13193
|
+
exitCode = 1;
|
|
13194
|
+
const partial = ask?.partialResult();
|
|
13195
|
+
if (partial && !conversationId) conversationId = partial.sessionId;
|
|
13196
|
+
outputAskError(wantsJson, message2, code, conversationId, partial);
|
|
13149
13197
|
} finally {
|
|
13150
13198
|
console.log = originalConsoleLog;
|
|
13151
13199
|
setSilentMode(false);
|
|
13152
13200
|
}
|
|
13153
|
-
process.exit(
|
|
13201
|
+
process.exit(exitCode);
|
|
13154
13202
|
}
|
|
13155
13203
|
async function executeAgentSessionsList(ctx2, options) {
|
|
13156
13204
|
const vault = await ctx2.ensureActiveVault();
|
|
@@ -13235,7 +13283,7 @@ var cachedVersion = null;
|
|
|
13235
13283
|
function getVersion() {
|
|
13236
13284
|
if (cachedVersion) return cachedVersion;
|
|
13237
13285
|
if (true) {
|
|
13238
|
-
cachedVersion = "2.
|
|
13286
|
+
cachedVersion = "2.8.0";
|
|
13239
13287
|
return cachedVersion;
|
|
13240
13288
|
}
|
|
13241
13289
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vultisig/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.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": {
|
|
@@ -75,8 +75,8 @@
|
|
|
75
75
|
"@noble/hashes": "^2.2.0",
|
|
76
76
|
"@vultisig/client-shared": "^0.2.16",
|
|
77
77
|
"@vultisig/core-chain": "^2.17.8",
|
|
78
|
-
"@vultisig/rujira": "^
|
|
79
|
-
"@vultisig/sdk": "^2.
|
|
78
|
+
"@vultisig/rujira": "^41.0.0",
|
|
79
|
+
"@vultisig/sdk": "^2.8.0",
|
|
80
80
|
"chalk": "^5.6.2",
|
|
81
81
|
"cli-table3": "^0.6.5",
|
|
82
82
|
"commander": "^15.0.0",
|