pandora-cli-skills 1.1.18 → 1.1.20

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.
@@ -30,6 +30,14 @@ function buildIdempotencyKey(options, quote, nowMs) {
30
30
  }
31
31
 
32
32
  function evaluateTrigger(options, quote) {
33
+ if (quote && quote.quoteAvailable === false) {
34
+ return {
35
+ triggered: false,
36
+ reason: 'quote unavailable; skipping trigger evaluation.',
37
+ yesPct: null,
38
+ };
39
+ }
40
+
33
41
  const yesPct = toNumber(quote && quote.odds && quote.odds.yesPct);
34
42
  if (yesPct === null) {
35
43
  return {
@@ -148,26 +156,40 @@ async function runAutopilot(options, deps) {
148
156
  snapshot.action = {
149
157
  mode: options.executeLive ? 'live' : 'paper',
150
158
  status: 'blocked',
151
- reason: `Exposure cap exceeded: ${(state.dailySpendUsdc + options.amountUsdc).toFixed(2)} > ${options.maxOpenExposureUsdc}.`,
159
+ reason: `Daily spend cap exceeded: ${(state.dailySpendUsdc + options.amountUsdc).toFixed(2)} > ${options.maxOpenExposureUsdc}.`,
152
160
  };
153
161
  } else {
162
+ let executionSucceeded = true;
154
163
  if (options.executeLive) {
155
- const execution = await deps.executeFn({
156
- marketAddress: options.marketAddress,
157
- side: options.side,
158
- amountUsdc: options.amountUsdc,
159
- yesPct: trigger.yesPct,
160
- maxAmountUsdc: options.maxAmountUsdc,
161
- minProbabilityPct: options.minProbabilityPct,
162
- maxProbabilityPct: options.maxProbabilityPct,
163
- });
164
+ try {
165
+ const execution = await deps.executeFn({
166
+ marketAddress: options.marketAddress,
167
+ side: options.side,
168
+ amountUsdc: options.amountUsdc,
169
+ yesPct: trigger.yesPct,
170
+ maxAmountUsdc: options.maxAmountUsdc,
171
+ minProbabilityPct: options.minProbabilityPct,
172
+ maxProbabilityPct: options.maxProbabilityPct,
173
+ });
164
174
 
165
- snapshot.action = {
166
- mode: 'live',
167
- status: 'executed',
168
- idempotencyKey: key,
169
- execution,
170
- };
175
+ snapshot.action = {
176
+ mode: 'live',
177
+ status: 'executed',
178
+ idempotencyKey: key,
179
+ execution,
180
+ };
181
+ } catch (err) {
182
+ executionSucceeded = false;
183
+ snapshot.action = {
184
+ mode: 'live',
185
+ status: 'failed',
186
+ idempotencyKey: key,
187
+ error: {
188
+ code: err && err.code ? String(err.code) : null,
189
+ message: err && err.message ? String(err.message) : String(err),
190
+ },
191
+ };
192
+ }
171
193
  } else {
172
194
  snapshot.action = {
173
195
  mode: 'paper',
@@ -178,10 +200,12 @@ async function runAutopilot(options, deps) {
178
200
  };
179
201
  }
180
202
 
181
- state.idempotencyKeys.push(key);
182
- pruneIdempotencyKeys(state);
183
- state.dailySpendUsdc = Number((state.dailySpendUsdc + options.amountUsdc).toFixed(6));
184
- state.tradesToday += 1;
203
+ if (executionSucceeded) {
204
+ state.idempotencyKeys.push(key);
205
+ pruneIdempotencyKeys(state);
206
+ state.dailySpendUsdc = Number((state.dailySpendUsdc + options.amountUsdc).toFixed(6));
207
+ state.tradesToday += 1;
208
+ }
185
209
  state.lastExecution = snapshot.action;
186
210
  actions.push(snapshot.action);
187
211
 
@@ -239,6 +263,7 @@ async function runAutopilot(options, deps) {
239
263
  cooldownMs: options.cooldownMs,
240
264
  maxAmountUsdc: options.maxAmountUsdc,
241
265
  maxOpenExposureUsdc: options.maxOpenExposureUsdc,
266
+ dailySpendCapUsdc: options.maxOpenExposureUsdc,
242
267
  maxTradesPerDay: options.maxTradesPerDay,
243
268
  },
244
269
  state,
@@ -54,6 +54,9 @@ function resolveDistribution(options = {}) {
54
54
  const explicitYes = toNumber(options.distributionYes);
55
55
  const explicitNo = toNumber(options.distributionNo);
56
56
  if (explicitYes !== null || explicitNo !== null) {
57
+ if (explicitYes === null || explicitNo === null) {
58
+ throw new Error('distributionYes and distributionNo must both be provided together.');
59
+ }
57
60
  if (!Number.isInteger(explicitYes) || !Number.isInteger(explicitNo)) {
58
61
  throw new Error('distributionYes and distributionNo must be integers.');
59
62
  }
@@ -73,6 +76,8 @@ function resolveDistribution(options = {}) {
73
76
  const distribution = computeDistributionHint(sourceYesPct === null ? 0.5 : sourceYesPct / 100);
74
77
  if (sourceYesPct === null) {
75
78
  diagnostics.push('No source YES probability supplied; defaulted to balanced 50/50 distribution hint.');
79
+ } else if (sourceYesPct === 0 || sourceYesPct === 100) {
80
+ diagnostics.push('Degenerate source YES probability (0% or 100%) may create an extreme one-sided seed.');
76
81
  }
77
82
 
78
83
  return {
@@ -186,7 +191,7 @@ function simulateDirectionalSwap(options = {}) {
186
191
  const denominator = reserveNo + effectiveIn;
187
192
  const outputYes = denominator > 0 ? (reserveYes * effectiveIn) / denominator : 0;
188
193
  const postReserveYes = Math.max(0, reserveYes - outputYes);
189
- const postReserveNo = reserveNo + volumeUsdc;
194
+ const postReserveNo = reserveNo + effectiveIn;
190
195
  return {
191
196
  side,
192
197
  volumeUsdc: round(volumeUsdc, 6),
@@ -203,7 +208,7 @@ function simulateDirectionalSwap(options = {}) {
203
208
  const denominator = reserveYes + effectiveIn;
204
209
  const outputNo = denominator > 0 ? (reserveNo * effectiveIn) / denominator : 0;
205
210
  const postReserveNo = Math.max(0, reserveNo - outputNo);
206
- const postReserveYes = reserveYes + volumeUsdc;
211
+ const postReserveYes = reserveYes + effectiveIn;
207
212
  return {
208
213
  side,
209
214
  volumeUsdc: round(volumeUsdc, 6),
@@ -270,26 +275,32 @@ function solveVolumeForTargetYesPct(options = {}) {
270
275
  }
271
276
 
272
277
  function normalizeVolumeScenarios(value, liquidityUsdc) {
278
+ const fallback = () => {
279
+ const liq = Math.max(1, toNumber(liquidityUsdc) || 0);
280
+ return [
281
+ round(liq * 0.25, 6),
282
+ round(liq * 0.5, 6),
283
+ round(liq, 6),
284
+ round(liq * 2, 6),
285
+ ];
286
+ };
287
+
273
288
  if (Array.isArray(value)) {
274
- return value.map((item) => toNumber(item)).filter((item) => Number.isFinite(item) && item >= 0).map((item) => round(item, 6));
289
+ const parsed = value.map((item) => toNumber(item)).filter((item) => Number.isFinite(item) && item >= 0).map((item) => round(item, 6));
290
+ return parsed.length ? parsed : fallback();
275
291
  }
276
292
 
277
293
  const raw = String(value || '').trim();
278
294
  if (raw) {
279
- return raw
295
+ const parsed = raw
280
296
  .split(',')
281
297
  .map((entry) => toNumber(entry.trim()))
282
298
  .filter((entry) => Number.isFinite(entry) && entry >= 0)
283
299
  .map((entry) => round(entry, 6));
300
+ return parsed.length ? parsed : fallback();
284
301
  }
285
302
 
286
- const liq = Math.max(1, toNumber(liquidityUsdc) || 0);
287
- return [
288
- round(liq * 0.25, 6),
289
- round(liq * 0.5, 6),
290
- round(liq, 6),
291
- round(liq * 2, 6),
292
- ];
303
+ return fallback();
293
304
  }
294
305
 
295
306
  function computeHedgeMetrics(options = {}) {
@@ -534,7 +545,7 @@ function buildMirrorSimulate(options = {}) {
534
545
  scenarios: scenarioResults,
535
546
  diagnostics: [
536
547
  'Complete-set mint/split step is exact (raw integer math).',
537
- 'Trade path models a CPMM-style directional flow with fees retained in reserves.',
548
+ 'Trade path models CPMM directional flow using net-of-fee input in reserve updates; fees are tracked as a separate accrual line.',
538
549
  'Use mirror sync + live orderbooks for execution-grade sizing; this command is planning-grade simulation.',
539
550
  ].concat(distribution.diagnostics || []),
540
551
  };
@@ -170,7 +170,7 @@ function resolveSpenders(options = {}, env = process.env) {
170
170
  function resolveRuntime(options = {}) {
171
171
  const env = options.env || process.env;
172
172
  const rpcUrl = options.rpcUrl || env.POLYMARKET_RPC_URL || env.RPC_URL || null;
173
- const privateKey = options.privateKey || env.POLYMARKET_PRIVATE_KEY || env.PRIVATE_KEY || null;
173
+ const privateKey = options.privateKey || env.POLYMARKET_PRIVATE_KEY || null;
174
174
  const funderAddress = normalizeAddress(options.funder || env.POLYMARKET_FUNDER, 'funder');
175
175
  const usdcAddress = normalizeAddress(options.usdcAddress || env.POLYMARKET_USDC_E_ADDRESS, 'usdcAddress')
176
176
  || POLYMARKET_POLYGON_DEFAULTS.usdc;
@@ -488,6 +488,25 @@ async function fetchJson(url, timeoutMs) {
488
488
  }
489
489
  }
490
490
 
491
+ async function callWithTimeout(work, timeoutMs, label) {
492
+ const limitMs = Number.isInteger(timeoutMs) && timeoutMs > 0 ? timeoutMs : null;
493
+ if (!limitMs) {
494
+ return work();
495
+ }
496
+
497
+ let timer = null;
498
+ try {
499
+ return await Promise.race([
500
+ work(),
501
+ new Promise((_, reject) => {
502
+ timer = setTimeout(() => reject(new Error(`${label} timed out after ${limitMs}ms`)), limitMs);
503
+ }),
504
+ ]);
505
+ } finally {
506
+ if (timer) clearTimeout(timer);
507
+ }
508
+ }
509
+
491
510
  function buildGammaUrl(baseUrl, params) {
492
511
  const url = new URL(`${baseUrl}/markets`);
493
512
  for (const [key, value] of Object.entries(params || {})) {
@@ -523,7 +542,7 @@ function extractConditionId(row) {
523
542
  return value;
524
543
  }
525
544
 
526
- async function resolveByClobDirect(conditionId, hosts, options, diagnostics) {
545
+ async function resolveByClobDirect(conditionId, hosts, options, diagnostics, timeoutMs) {
527
546
  const hostErrors = [];
528
547
  for (const candidateHost of hosts) {
529
548
  try {
@@ -534,7 +553,11 @@ async function resolveByClobDirect(conditionId, hosts, options, diagnostics) {
534
553
  if (!client || typeof client.getMarket !== 'function') {
535
554
  throw new Error('CLOB client does not expose getMarket.');
536
555
  }
537
- const market = await client.getMarket(conditionId);
556
+ const market = await callWithTimeout(
557
+ () => client.getMarket(conditionId),
558
+ timeoutMs,
559
+ `Polymarket getMarket(${conditionId})`,
560
+ );
538
561
  if (!market) continue;
539
562
  return {
540
563
  row: market,
@@ -604,7 +627,7 @@ async function resolvePolymarketMarket(options = {}) {
604
627
  }
605
628
 
606
629
  if (directConditionId && isConditionId(directConditionId)) {
607
- const direct = await resolveByClobDirect(directConditionId, hosts, options, diagnostics);
630
+ const direct = await resolveByClobDirect(directConditionId, hosts, options, diagnostics, timeoutMs);
608
631
  if (direct && direct.row) {
609
632
  rows = [direct.row];
610
633
  hostUsed = direct.host;
@@ -632,7 +655,11 @@ async function resolvePolymarketMarket(options = {}) {
632
655
 
633
656
  while (loops < maxPages) {
634
657
  loops += 1;
635
- const page = cursor ? await client.getMarkets(cursor) : await client.getMarkets();
658
+ const page = await callWithTimeout(
659
+ () => (cursor ? client.getMarkets(cursor) : client.getMarkets()),
660
+ timeoutMs,
661
+ `Polymarket getMarkets(${candidateHost})`,
662
+ );
636
663
  const chunk = Array.isArray(page && page.data) ? page.data : [];
637
664
 
638
665
  if (selectorMode) {
@@ -790,7 +817,7 @@ function calculateExecutableDepthUsd(orderbook, side, slippageBps) {
790
817
  };
791
818
  }
792
819
 
793
- async function getOrderbook(clientOrOptions, tokenId, fallbackOrderbooks = null) {
820
+ async function getOrderbook(clientOrOptions, tokenId, fallbackOrderbooks = null, timeoutMs = null) {
794
821
  if (!tokenId) return null;
795
822
 
796
823
  if (fallbackOrderbooks && typeof fallbackOrderbooks === 'object' && fallbackOrderbooks[tokenId]) {
@@ -801,11 +828,16 @@ async function getOrderbook(clientOrOptions, tokenId, fallbackOrderbooks = null)
801
828
  return null;
802
829
  }
803
830
 
804
- return clientOrOptions.getOrderBook(tokenId);
831
+ return callWithTimeout(
832
+ () => clientOrOptions.getOrderBook(tokenId),
833
+ timeoutMs,
834
+ `Polymarket getOrderBook(${tokenId})`,
835
+ );
805
836
  }
806
837
 
807
838
  async function fetchDepthForMarket(market, options = {}) {
808
839
  const slippageBps = Number.isFinite(Number(options.slippageBps)) ? Number(options.slippageBps) : 100;
840
+ const timeoutMs = Number.isInteger(options.timeoutMs) && options.timeoutMs > 0 ? options.timeoutMs : 12_000;
809
841
  const diagnostics = [];
810
842
  const hosts = normalizeHostList(options.host || options.hosts || process.env.POLYMARKET_HOSTS || DEFAULT_POLYMARKET_HOST);
811
843
  const cacheFile =
@@ -825,8 +857,8 @@ async function fetchDepthForMarket(market, options = {}) {
825
857
  for (const candidateHost of hosts) {
826
858
  try {
827
859
  const client = new ClobClient(candidateHost, DEFAULT_POLYMARKET_CHAIN);
828
- const yesFromHost = await getOrderbook(client, market.yesTokenId, null);
829
- const noFromHost = await getOrderbook(client, market.noTokenId, null);
860
+ const yesFromHost = await getOrderbook(client, market.yesTokenId, null, timeoutMs);
861
+ const noFromHost = await getOrderbook(client, market.noTokenId, null, timeoutMs);
830
862
  yesBook = yesFromHost || yesBook;
831
863
  noBook = noFromHost || noBook;
832
864
  if (yesFromHost || noFromHost) {
@@ -1289,10 +1321,15 @@ async function fetchPolymarketPositionSummary(options = {}) {
1289
1321
  const fetchBalance = async (tokenId, sideLabel) => {
1290
1322
  if (!tokenId) return;
1291
1323
  try {
1292
- const response = await client.getBalanceAllowance({
1293
- asset_type: AssetType.CONDITIONAL,
1294
- token_id: tokenId,
1295
- });
1324
+ const response = await callWithTimeout(
1325
+ () =>
1326
+ client.getBalanceAllowance({
1327
+ asset_type: AssetType.CONDITIONAL,
1328
+ token_id: tokenId,
1329
+ }),
1330
+ timeoutMs,
1331
+ `Polymarket getBalanceAllowance(${tokenId})`,
1332
+ );
1296
1333
  if (responseContainsError(response)) {
1297
1334
  diagnostics.push(
1298
1335
  `${sideLabel} balance lookup failed: ${response && response.error ? response.error : `HTTP ${response && response.status ? response.status : 'error'}`}.`,
@@ -1317,14 +1354,30 @@ async function fetchPolymarketPositionSummary(options = {}) {
1317
1354
  let openOrders = null;
1318
1355
  try {
1319
1356
  if (baseSummary.marketId) {
1320
- openOrders = await client.getOpenOrders({ market: baseSummary.marketId });
1357
+ openOrders = await callWithTimeout(
1358
+ () => client.getOpenOrders({ market: baseSummary.marketId }),
1359
+ timeoutMs,
1360
+ `Polymarket getOpenOrders(market:${baseSummary.marketId})`,
1361
+ );
1321
1362
  } else {
1322
1363
  const grouped = [];
1323
1364
  if (baseSummary.yesTokenId) {
1324
- grouped.push(await client.getOpenOrders({ asset_id: baseSummary.yesTokenId }));
1365
+ grouped.push(
1366
+ await callWithTimeout(
1367
+ () => client.getOpenOrders({ asset_id: baseSummary.yesTokenId }),
1368
+ timeoutMs,
1369
+ `Polymarket getOpenOrders(asset:${baseSummary.yesTokenId})`,
1370
+ ),
1371
+ );
1325
1372
  }
1326
1373
  if (baseSummary.noTokenId && baseSummary.noTokenId !== baseSummary.yesTokenId) {
1327
- grouped.push(await client.getOpenOrders({ asset_id: baseSummary.noTokenId }));
1374
+ grouped.push(
1375
+ await callWithTimeout(
1376
+ () => client.getOpenOrders({ asset_id: baseSummary.noTokenId }),
1377
+ timeoutMs,
1378
+ `Polymarket getOpenOrders(asset:${baseSummary.noTokenId})`,
1379
+ ),
1380
+ );
1328
1381
  }
1329
1382
  const dedup = new Map();
1330
1383
  for (const group of grouped) {
package/cli/pandora.cjs CHANGED
@@ -2954,7 +2954,7 @@ function parseMirrorDeployFlags(args) {
2954
2954
  continue;
2955
2955
  }
2956
2956
  if (token === '--private-key') {
2957
- options.privateKey = requireFlagValue(args, i, '--private-key');
2957
+ options.privateKey = parsePrivateKeyFlag(requireFlagValue(args, i, '--private-key'), '--private-key');
2958
2958
  i += 1;
2959
2959
  continue;
2960
2960
  }
@@ -4434,6 +4434,7 @@ function parsePolymarketTradeFlags(args) {
4434
4434
  dryRun: false,
4435
4435
  execute: false,
4436
4436
  host: null,
4437
+ timeoutMs: DEFAULT_INDEXER_TIMEOUT_MS,
4437
4438
  rpcUrl: null,
4438
4439
  privateKey: null,
4439
4440
  funder: null,
@@ -4485,6 +4486,11 @@ function parsePolymarketTradeFlags(args) {
4485
4486
  i += 1;
4486
4487
  continue;
4487
4488
  }
4489
+ if (token === '--timeout-ms') {
4490
+ options.timeoutMs = parsePositiveInteger(requireFlagValue(args, i, '--timeout-ms'), '--timeout-ms');
4491
+ i += 1;
4492
+ continue;
4493
+ }
4488
4494
  if (token === '--dry-run') {
4489
4495
  options.dryRun = true;
4490
4496
  continue;
@@ -9768,7 +9774,7 @@ async function runPolymarketCommand(args, context) {
9768
9774
  console.log(' approve --dry-run|--execute [--rpc-url <url>] [--private-key <hex>] [--funder <address>]');
9769
9775
  console.log(' preflight [--rpc-url <url>] [--private-key <hex>] [--funder <address>]');
9770
9776
  console.log(
9771
- ' trade --condition-id <id>|--slug <slug>|--token-id <id> --token yes|no --amount-usdc <n> --dry-run|--execute [--side buy|sell] [--polymarket-host <url>] [--rpc-url <url>] [--private-key <hex>] [--funder <address>]',
9777
+ ' trade --condition-id <id>|--slug <slug>|--token-id <id> --token yes|no --amount-usdc <n> --dry-run|--execute [--side buy|sell] [--polymarket-host <url>] [--timeout-ms <ms>] [--rpc-url <url>] [--private-key <hex>] [--funder <address>]',
9772
9778
  );
9773
9779
  }
9774
9780
  return;
@@ -9847,7 +9853,7 @@ async function runPolymarketCommand(args, context) {
9847
9853
  if (action === 'trade') {
9848
9854
  if (includesHelpFlag(actionArgs)) {
9849
9855
  const usage =
9850
- 'pandora [--output table|json] polymarket trade --condition-id <id>|--slug <slug>|--token-id <id> --token yes|no --amount-usdc <n> --dry-run|--execute [--side buy|sell] [--polymarket-host <url>] [--rpc-url <url>] [--private-key <hex>] [--funder <address>]';
9856
+ 'pandora [--output table|json] polymarket trade --condition-id <id>|--slug <slug>|--token-id <id> --token yes|no --amount-usdc <n> --dry-run|--execute [--side buy|sell] [--polymarket-host <url>] [--timeout-ms <ms>] [--rpc-url <url>] [--private-key <hex>] [--funder <address>]';
9851
9857
  if (context.outputMode === 'json') {
9852
9858
  emitSuccess(context.outputMode, 'polymarket.trade.help', commandHelpPayload(usage));
9853
9859
  } else {
@@ -9862,7 +9868,7 @@ async function runPolymarketCommand(args, context) {
9862
9868
  if (!tokenId) {
9863
9869
  market = await resolvePolymarketMarket({
9864
9870
  host: options.host || process.env.POLYMARKET_HOST || null,
9865
- timeoutMs: DEFAULT_INDEXER_TIMEOUT_MS,
9871
+ timeoutMs: options.timeoutMs,
9866
9872
  marketId: options.conditionId,
9867
9873
  slug: options.slug,
9868
9874
  });
@@ -10126,38 +10132,47 @@ async function runSuggestCommand(args, context) {
10126
10132
  maybeLoadIndexerEnv(shared);
10127
10133
  const indexerUrl = resolveIndexerUrl(shared.indexerUrl);
10128
10134
  const options = parseSuggestFlags(shared.rest);
10129
- const history = await fetchHistory({
10130
- wallet: options.wallet,
10131
- chainId: null,
10132
- marketAddress: null,
10133
- side: 'both',
10134
- status: 'all',
10135
- limit: 250,
10136
- after: null,
10137
- before: null,
10138
- orderBy: 'timestamp',
10139
- orderDirection: 'desc',
10140
- includeSeed: false,
10141
- indexerUrl,
10142
- timeoutMs: shared.timeoutMs,
10143
- });
10144
- const arbitrage = await scanArbitrage({
10145
- indexerUrl,
10146
- timeoutMs: shared.timeoutMs,
10147
- chainId: null,
10148
- venues: options.includeVenues,
10149
- limit: Math.max(options.count * 3, 10),
10150
- minSpreadPct: 3,
10151
- minLiquidityUsd: 1000,
10152
- maxCloseDiffHours: 24,
10153
- similarityThreshold: 0.86,
10154
- crossVenueOnly: true,
10155
- withRules: false,
10156
- includeSimilarity: false,
10157
- questionContains: null,
10158
- polymarketHost: null,
10159
- polymarketMockUrl: null,
10160
- });
10135
+ let history;
10136
+ let arbitrage;
10137
+ try {
10138
+ history = await fetchHistory({
10139
+ wallet: options.wallet,
10140
+ chainId: null,
10141
+ marketAddress: null,
10142
+ side: 'both',
10143
+ status: 'all',
10144
+ limit: 250,
10145
+ after: null,
10146
+ before: null,
10147
+ orderBy: 'timestamp',
10148
+ orderDirection: 'desc',
10149
+ includeSeed: false,
10150
+ indexerUrl,
10151
+ timeoutMs: shared.timeoutMs,
10152
+ });
10153
+ arbitrage = await scanArbitrage({
10154
+ indexerUrl,
10155
+ timeoutMs: shared.timeoutMs,
10156
+ chainId: null,
10157
+ venues: options.includeVenues,
10158
+ limit: Math.max(options.count * 3, 10),
10159
+ minSpreadPct: 3,
10160
+ minLiquidityUsd: 1000,
10161
+ maxCloseDiffHours: 24,
10162
+ similarityThreshold: 0.86,
10163
+ crossVenueOnly: true,
10164
+ withRules: false,
10165
+ includeSimilarity: false,
10166
+ questionContains: null,
10167
+ polymarketHost: null,
10168
+ polymarketMockUrl: null,
10169
+ });
10170
+ } catch (err) {
10171
+ if (err && err.code) {
10172
+ throw new CliError(err.code, err.message || 'suggest failed.', err.details);
10173
+ }
10174
+ throw err;
10175
+ }
10161
10176
 
10162
10177
  const suggestions = buildSuggestions({
10163
10178
  wallet: options.wallet,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pandora-cli-skills",
3
- "version": "1.1.18",
3
+ "version": "1.1.20",
4
4
  "description": "Pandora CLI & Skills",
5
5
  "main": "cli/pandora.cjs",
6
6
  "bin": {